知识预备web
什么是仿射变换?spa
从视觉效果上来理解,仿射变换是经过一系列原子变换复合而来的变换。包括:平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和错切(Shear)(图像的错切其实是平面景物在投影平面上的非垂直投影)。.net
iOS 视图的 frame 和 bounds 属性的区别code
frame 描述了该视图在父视图坐标系统中的位置和大小,其参照点是父视图的坐标系统。 bounds 描述了该视图在本地坐标系统中的位置和大小,其参照点是该视图本身的坐标系统。 若是还有疑惑,能够点击下方连接,这篇博文确切地解释了区别所在。 iOS 视图的 frame 和 bounds 属性的区别orm
3.UIGestureRecognizerState 的参数值(状态)对象
UIGestureRecognizerStatePossible : 手势识别器尚未识别出手势,可是可能正在估算触摸事件(touches event),还处在判断阶段。这个状态是手势识别器的默认状态。blog
UIGestureRecognizerStateBegan : 手势识别器已经接收到了一系列触摸而且识别出了它属于哪一个手势。响应方法在下一个运行周期被调用。继承
UIGestureRecognizerStateChanged : 手势识别器已经接收到了一系列触摸而且识别出手势发生了改变。响应方法在下一个运行周期被调用。事件
UIGestureRecognizerStateEnded : 手势识别器已经接收到了一系列触摸而且识别出手势刚刚结束。响应方法在下一个运行周期被调用,而且把手势状态的值从新置为 UIGestureRecognizerStatePossible。图片
UIGestureRecognizerStateCancelled : 手势识别器已经接收到了一系列触摸而且识别出手势忽然中断。响应方法在下一个运行周期被调用,而且把手势状态的值从新置为 UIGestureRecognizerStatePossible。
UIGestureRecognizerStateFailed : 手势识别器已经接收到了一系列多点触控,可是与识别器认识的手势匹配失败(识别不出来)。无响应方法。把手势状态的值从新置为 UIGestureRecognizerStatePossible。
UIGestureRecognizerStateRecognized : 手势识别器已经接收到了一系列多点触控,而且识别器识别出该手势。响应方法在下一个运行周期被调用,而且把手势状态的值从新置为 UIGestureRecognizerStatePossible。
建立工程步骤请参照 实战1中的前几步。
在工程中建立一个 MyImageView 视图类,继承自 UIImageView。
首先为咱们建立的视图类进行初始化方法的编写,在 MyImageView.m 文件中:
static int count; @implementation MyImageView { CGPoint previousLocation; UIPanGestureRecognizer *panGestureRecognizer; } #pragma mark - initialization - (id) initWithImage:(UIImage *)image { self = [super initWithImage:image]; if (self) { self.userInteractionEnabled = YES; // 在视图被初始化的过程当中,建立一个 拖动手势识别器 // 应用 target-action 模式,以该类为目标对象,若是手势被触发,handlePan: 方法会被调用 panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; // 该类的实例对象可以被 拖动手势识别器 所识别 self.gestureRecognizers = @[panGestureRecognizer]; } return self; } - (id) init { // 图片文件的名称为 blue.png return [self initWithImage:[UIImage imageNamed:@"blue"]]; } #pragma mark - touches mothods are called // 当该类的实例对象被触碰的时候,该方法会被触发 - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.superview bringSubviewToFront:self]; // 视图中心点 previousLocation = self.center; } #pragma mark - selector handlePan: - (void) handlePan:(UIPanGestureRecognizer *) gestureRecognizer { // print 该方法的运行次数 NSLog(@"%i", ++count); // 根据视图的仿射变换来获取偏移量 CGPoint translation = [gestureRecognizer translationInView:self.superview]; // 重置视图中心点 self.center = CGPointMake(previousLocation.x + translation.x, previousLocation.y + translation.y); }
在 ViewController.m 文件中写入代码:
- (void)viewDidLoad { [super viewDidLoad]; // 建立类实例而且添加视图 _myImageView = [[MyImageView alloc] initWithImage:[UIImage imageNamed:@"blue"]]; [self.view addSubview:_myImageView]; }
运行结果: 视图可以响应拖动手势,在屏幕上被拖动。控制台显示结果标明, handlePan: 方法在拖动手势进行过程当中,一直都在被调用,直至手势中止。
为了让自定义视图可以响应手势,咱们在建立而且初始化视图类实例的时候,就应该建立响应的手势识别器及其会响应的方法,当手势在进行过程当中时,响应方法被反复调用,直至手势中止。为了让视图可以跟随手势移动,咱们只需根据视图先前的中心位置和被拖动之后的偏移位置来从新设定视图的中心位置便可。
Jan 31, 2015