通过touchesMoved实现缩放手势效果

2023-08-16  本文已影响0人  大佬papp

因为公司要求,对view添加了许多手势,但是对于捏合手势有个问题.
如果view过小,捏合手势无法触发. 所以选择通过touched方法来进一步实现 具体代码如下


@property (nonatomic,nullable, strong)UIView * respondsView; /// <--------手势响应的View
@property (nonatomic,assign)CGPoint beginPoint;/// <--------手势响应的起始点
@property (nonatomic,assign)CGPoint changePoint;/// <--------手势响应的变更点
@property (nonatomic, assign)CGAffineTransform  transform;///< ------缓存出事from
@property(nonatomic,assign)CGFloat startDistance;//< ------缓存起始点
@property(nonatomic,assign)CGFloat scale;  /// < ------缓存缩放比例
@property(nonatomic,assign)BOOL isSet;  /// < ------是否设置过transform
@property(nonatomic,assign)BOOL isPan; ///<---是否是刚刚触发了拖动手势
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    //如果响应view存在,说明现在beginPoint有值
    if(self.respondsView){
        UITouch * touch =  [touches anyObject];
        CGPoint point = [touch locationInView:self.view];
        self.changePoint=point;
        // 计算起始位置的距离
        self.startDistance = hypot (self.beginPoint.x - self.changePoint.x, self.beginPoint.y - self.changePoint.y);
        // 初始化scale值
        self.scale = 1.0;
    }

}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    if(self.respondsView){
        UITouch * touch =  [touches anyObject];
        CGPoint point = [touch locationInView:self.view];
        //表示起始位置的距离,
        CGFloat currentDistance = hypot (self.beginPoint.x - point.x, self.beginPoint.y - point.y);
        self.scale = (currentDistance / self.startDistance) * 1.0;
        if(!self.isSet){
            self.transform=self.respondsView.transform;
            self.isSet=YES;
        }
        
        self.respondsView.transform = CGAffineTransformScale(self.transform, self.scale, self.scale);
        self.scale = 1.0;
        
    }
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    if(self.respondsView){
        self.transform=self.respondsView.transform;

    }
}

-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    DLog(@"结束了");

}
#pragma mark --clickFunc
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}
-(void)tapClick:(UITapGestureRecognizer *)tap{
    [self beginEditTextWithClickView:tap.view];
}
-(void)panClick:(UIPanGestureRecognizer*)sender{
    
    CGPoint curtPoint = [sender locationInView:self.view];
    self.beginPoint=curtPoint;
    // 偏移点
    CGPoint translation = [sender translationInView:self.view];
    int minY = self.deleteBtn.top;
    int minX = self.deleteBtn.left;
    int MaxY = self.deleteBtn.top+self.deleteBtn.height;
    int MaxX = self.deleteBtn.left+self.deleteBtn.width;
    
    if(self.editAlertView){
        
        [self.editAlertView remove];
        
    }
    if(!self.respondsView){
        self.respondsView=sender.view;
    }else{
        if(![sender.view isEqual:self.respondsView]){
            return;
        }
    }
    
    
    if(sender.state==UIGestureRecognizerStateBegan){
        
        self.bottomView.hidden=YES;
        self.deleteBtn.hidden=NO;
        beginPoint=CGPointMake(sender.view.center.x, sender.view.center.y);
        DLog(@"pint x:%f,y:%f",sender.view.center.x,sender.view.center.y);

    }
    if (sender.state == UIGestureRecognizerStateChanged) {
        if(curtPoint.x>=minX && curtPoint.x<=MaxX && curtPoint.y>minY && curtPoint.y<=MaxY){
            if(!self.deleteBtn.selected){
                [UtilTools playSystemSound];
            }
            self.deleteBtn.selected=YES;
            
        }else{
            if(self.deleteBtn.selected){
                [UtilTools playSystemSound];
                self.deleteBtn.selected=NO;
            }
        }
        sender.view.center = CGPointMake(sender.view.center.x + translation.x, sender.view.center.y + translation.y);
        [sender setTranslation:CGPointZero inView:self.backImg];
        
        self.isPan=YES;
    }
    if(sender.state ==UIGestureRecognizerStateEnded ){
        //删除操作
        if(curtPoint.x>=minX && curtPoint.x<=MaxX && curtPoint.y>minY && curtPoint.y<=MaxY){
            [self deleteSubViewWithData:sender.view];
            self.deleteBtn.selected=NO;
        }else if(curtPoint.y>WIDTH+kNavHeight){
            [UIView animateWithDuration:0.2 animations:^{
                sender.view.center=self->beginPoint;
            }];
            
        }
        [UIView animateWithDuration:0.2 animations:^{
            self.bottomView.hidden=NO;
            self.deleteBtn.hidden=YES;
        }];
        [self touchCanle];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.isPan=NO;
        });
    }
 
}

-(void)longClick:(UILongPressGestureRecognizer*)sender{
    CGPoint point = [sender locationInView:self.view];
    
    //这里要加三重判断
    if(!self.editAlertView && !self.respondsView && !self.isPan){
        
    }
    
}

-(void)pinClick:(UIPinchGestureRecognizer*)sender{
    UIView * senderView = sender.view;
    DLog(@"senderScanle:%f",sender.scale);
    senderView.transform = CGAffineTransformScale(senderView.transform, sender.scale, sender.scale);
    sender.scale = 1.0;
    if(!self.respondsView){
        self.respondsView=sender.view;
    }else{
        if(![sender.view isEqual:self.respondsView]){
            return;
        }
    }
    
    if(sender.state==UIGestureRecognizerStateEnded){
        if(self.respondsView){
            self.transform=self.respondsView.transform;
            self.isSet=YES;
        }
        [self touchCanle];
        
    }
}

-(void)rotationClick:(UIRotationGestureRecognizer*)sender{
    //获取旋转的角度
    CGFloat scale = sender.rotation;
        // 设置view的角度,使用transform设置
    sender.view.transform = CGAffineTransformRotate(sender.view.transform, scale);
    if(self.respondsView){
        self.transform=sender.view.transform;
        self.isSet=YES;
    }
    [sender setRotation:0];

    if(sender.state==UIGestureRecognizerStateEnded){
        [self touchCanle];
    }
}

重要的问题在于对于计算位置的缓存,和transform的刷新.刚写完,在此记录一下

上一篇下一篇

猜你喜欢

热点阅读