IOS图片拖拽.旋转.缩放

iOS上实现图片的拖拽,旋转,缩放还是比较简单的,将手势变化转换成矩阵变换就可以实现了

### 涉及的知识点:

1.拖拽手势 UIPanGestureRecognizer

2.捏合手势 UIPinchGestureRecognizer

3.旋转手势 UIRotationGestureRecognizer

4.矩阵变换 CGAffineTransform

5.缩放的计算与弧度计算


UIImageView *imgvCtrl = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 30, 30)];
    imgvCtrl.center = [imgv2 convertPoint:CGPointMake(200, 0) toView:imgvCtrl];
    imgvCtrl.image = [UIImage imageNamed:@"ic_trl"];
    imgvCtrl.userInteractionEnabled = YES;
    [self.view addSubview:imgvCtrl];
    
    UIPanGestureRecognizer *gesture5 = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(onScaleAndRotate:)];
    [imgvCtrl addGestureRecognizer:gesture5];


### 拖拽图片

给图片添加拖拽手势

UIPanGestureRecognizer *gesture1 = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(onDrag:)];
    [imgv1 addGestureRecognizer:gesture1];
ondrag:方法具体实现

-(void)onDrag:(UIPanGestureRecognizer*)gesture
{
    CGPoint translation = [gesture translationInView:self.view];
    CGPoint center = gesture.view.center;
    center.x += translation.x;
    center.y += translation.y;
    gesture.view.center = center;
    [gesture setTranslation:CGPointZero inView:self.view];
    
}

### 旋转图片

添加手势

UIRotationGestureRecognizer *gesture2 = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(onRotate:)];
    [imgv1 addGestureRecognizer:gesture2];
onRotate:方法的实现

-(void)onRotate:(UIRotationGestureRecognizer*)gesture
{
    gesture.view.transform = CGAffineTransformRotate(gesture.view.transform, gesture.rotation);
    gesture.rotation = 0;
}

### 缩放图片

添加手势

UIPinchGestureRecognizer *gesture3 = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(onScale:)];
    [imgv1 addGestureRecognizer:gesture3];

onScale:方法实现

-(void)onScale:(UIPinchGestureRecognizer*)gesture
{
    gesture.view.transform = CGAffineTransformScale(gesture.view.transform, gesture.scale, gesture.scale);
    gesture.scale = 1;
}


以上控制图片的旋转缩放都是双指操作的,那么下面再实现一个单指缩放旋转图片的吧。大概思路如下:

1.添加图片imgv2self.view

imgv2 = [[UIImageView alloc]initWithFrame:CGRectMake(70, 300, 200, 200)];
    imgv2.image = [UIImage imageNamed:@"img2"];
    [self.view addSubview:imgv2];
2.添加 imgv2的控制柄 imgvCtrl,实现 imgvCtrl的拖拽手势

UIImageView *imgvCtrl = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 30, 30)];
    imgvCtrl.center = [imgv2 convertPoint:CGPointMake(200, 0) toView:imgvCtrl];
    imgvCtrl.image = [UIImage imageNamed:@"ic_trl"];
    imgvCtrl.userInteractionEnabled = YES;
    [self.view addSubview:imgvCtrl];
    
    UIPanGestureRecognizer *gesture5 = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(onScaleAndRotate:)];
    [imgvCtrl addGestureRecognizer:gesture5];
3.实现拖拽手势 onScaleAndRotate: ,将拖拽手势转换成图片的旋转角度与缩放值

-(void)onScaleAndRotate:(UIPanGestureRecognizer*)gesture
{
    UIView *viewCtrl = gesture.view;
    UIView *viewImg = imgv2;
    
    CGPoint center = viewImg.center;
    CGPoint prePoint = viewCtrl.center;
    CGPoint translation = [gesture translationInView:gesture.view];
    CGPoint curPoint = CGPointMake(prePoint.x+translation.x, prePoint.y+translation.y);
    
    
    // 计算缩放
    CGFloat preDistance = [self getDistance:prePoint withPointB:center];
    CGFloat curDistance = [self getDistance:curPoint withPointB:center];
    CGFloat scale = curDistance / preDistance;
    
    // 计算弧度
    CGFloat preRadius = [self getRadius:center withPointB:prePoint];
    CGFloat curRadius = [self getRadius:center withPointB:curPoint];
    CGFloat radius = curRadius - preRadius;
    radius = - radius;
    
    CGAffineTransform transform = CGAffineTransformScale(viewImg.transform, scale, scale);
    viewImg.transform = CGAffineTransformRotate(transform, radius);
    
    
    
    viewCtrl.center = [viewImg convertPoint:CGPointMake(200, 0) toView:self.view];
    
    [gesture setTranslation:CGPointZero inView:viewCtrl];
}

4.涉及的计算距离与计算角度的方法

-(CGFloat)getDistance:(CGPoint)pointA withPointB:(CGPoint)pointB
{
    CGFloat x = pointA.x - pointB.x;
    CGFloat y = pointA.y - pointB.y;
    
    return sqrt(x*x + y*y);
}

-(CGFloat)getRadius:(CGPoint)pointA withPointB:(CGPoint)pointB
{
    CGFloat x = pointA.x - pointB.x;
    CGFloat y = pointA.y - pointB.y;
    return atan2(x, y);
}



### 需要注意的地方

像缩放,旋转的手势都不是即时手势,会有一个状态的延续,在我们的图片控制中,不需要状态的延续,需要把他们设置为初始值:

gesture.scale = 1; // 缩放手势中缩放系数归1

gesture.rotation = 0; // 旋转手势中 旋转弧度归0

[gesture setTranslation:CGPointZero inView:self.view]; //拖拽手势中,移动距离归0

相对坐标变换也是很容易混淆的地方,切记切记


### 开放思维

双指控制图片时候,只允许一个手势响应,也就是说旋转的时候无法缩放,缩放的时候无法旋转,通过继承UIGestureRecognizer 实现同时支持缩放与旋转的手势


附上demo:

http://download.csdn.net/detail/luguogege/9423165


附上图片:

IOS图片拖拽.旋转.缩放_第1张图片









你可能感兴趣的:(ios学习,图片,手势,旋转,缩放,单指)