zoukankan      html  css  js  c++  java
  • iOS_38_手势

    Pan平移手势
    终于效果图:

    Swipe轻扫手势


    LongPress长按手势



    Pinch和Rotation手势


    捏合(缩放)和旋转


    终于效果图:



    涂鸦

    终于效果图:



    事件分3大类:触摸、加速计、远程遥控

    仅仅有响应者的子类,才干够接收和处理事件

    父类响应者中定义的事件处理接口例如以下:

    触摸事件处理的四个方法例如以下:(仅仅要实现,系统会自己主动调用)

    一个UITouch对象,代表着一根手指,手指移动,UITouch对象实时更新

    一个UITouch对象,相应一根手指,记录着触摸时的全部信息

    重要~常常使用UITouch的方法,取得触摸时的信息(如位置、所点对象)

    事件对象UIEvent,经常使用的属性是:事件类型

    触摸的四个方法(即过程)具体解释:注意同一时候和一前一后触摸的情况

    必须先找到事件的最合适的响应者(从父到子地找)

    以下是寻找最合适的事件响应者详细样例:

    特殊情况:要尤其注意

    找到了事件的最佳处理者之后,就是响应者链条了
    默认是会调用其[super touchesXXX],这个super就是上一个响应者
    即:官方文档中的next responder

    以下是官方文档中关于上一个响应者的图片,即Next Responder

    总结起来就是:view有控制器,则传给控制器;否则,传给父view

    再次总结:响应者链条传递机制(上一个响应者就是NEXT RESPONDER)

    传统监听事件的做法:(不再推荐使用)

    六种手势识别器,后面会详细举例:
    假设要同一时候监听两种以上的手势:
    为每个手势设置delegate,而且实现以下的方法

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)



    手势识别器的标准做法:三步曲(创建、设置、绑定)

    重点关注三种手势识别的状态:開始结束取消

    官方文档中关于手势识别的状态变化图

    手势识别器的代理方法<UIGestureRecognizerDelegate>
    当中:shouldReceiveTouch能够指定手势在特定条件下有效

    shouldRecognizeSimultaneouslyWithGestureRecognizer

    返回YES代表能够同一时候识别不同手势,如同一时候旋转和缩放



    Pan平移手势
    终于效果图:

    //
    //  PanController.m
    //  38_手势
    //
    //  Created by beyond on 14-9-16.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "PanController.h"
    
    @interface PanController ()
    // nana头像所在的View
    @property (weak, nonatomic) IBOutlet UIView *nanaView;
    - (IBAction)dismiss;
    
    @end
    
    @implementation PanController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // 创建pan手势,并绑定监听方法
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];
        [self.nanaView addGestureRecognizer:pan];
    }
    
    - (void)panView:(UIPanGestureRecognizer *)pan
    {
        
        switch (pan.state) {
            case UIGestureRecognizerStateBegan: // 開始触发手势
                
                break;
                
            case UIGestureRecognizerStateEnded: // 手势结束
                
                break;
                
            default:
                break;
        }
        
        // 1.在view上面挪动的距离
        CGPoint translation = [pan translationInView:pan.view];
        CGPoint center = pan.view.center;
        center.x += translation.x;
        center.y += translation.y;
        pan.view.center = center;
        
        // 2.清空移动的距离
        [pan setTranslation:CGPointZero inView:pan.view];
    }
    
    #pragma mark - 连线
    - (IBAction)dismiss
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    @end
    


    Tap手势
    //
    //  TapController.m
    //  38_手势
    //
    //  Created by beyond on 14-9-16.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "TapController.h"
    
    // 手势代理
    @interface TapController ()<UIGestureRecognizerDelegate>
    
    @property (weak, nonatomic) IBOutlet UIImageView *nanaImgView;
    
    - (IBAction)dismiss;
    
    @end
    
    @implementation TapController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        _nanaImgView.userInteractionEnabled = YES;
        _nanaImgView.multipleTouchEnabled = YES;
        //[self testTap];
        [self testTap2];
    }
    
    - (void)testTap
    {
        // 1.创建Tap手势识别器对象
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
        // 两根手势,连续敲击2次,手势才干识别成功
        tap.numberOfTapsRequired = 2;
        tap.numberOfTouchesRequired = 2;
        
        // 2.加入监听方法(识别到了相应的手势,就会调用监听方法)
        [tap addTarget:self action:@selector(taping)];
        
        // 3.为nanaImgView 加入Tap手势识别器对象
        [self.nanaImgView addGestureRecognizer:tap];
    }
    
    - (void)testTap2
    {
        // 1.创建Tap手势识别器对象,同一时候绑定监听方法(识别到了相应的手势,就会调用监听方法)
        UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(taping)];
        // 2.设置手势的代理,目的是:决定手势仅仅有在特定场合才会被识别(触发监听的方法)
        tap.delegate = self;
        // 3.为nanaImgView 加入Tap手势识别器对象
        [self.nanaImgView addGestureRecognizer:tap];
    }
    #define kRandomColor [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1.0]
    // 监听的方法
    - (void)taping
    {
        // 每次tap,随机变换背景颜色
        self.view.backgroundColor = kRandomColor;
        NSLog(@"-----taping");
    }
    #pragma mark - gestureRecognizer的代理方法
    //  当点击view的时候,会先询问这种方法,是否接收本次tap点击(即是否为有效tap)
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        CGPoint pos = [touch locationInView:touch.view];
        // 点击图片的左半边有效,右半边无效
        if (pos.x <= self.nanaImgView.frame.size.width * 0.5) {
            return YES;
        }
        return NO;
    }
    
    
    
    
    #pragma mark - 连线方法
    - (IBAction)dismiss
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    @end
    

    Swipe轻扫手势


    LongPress长按手势




    长按手势的主要属性參数



    //
    //  SwipeLongPressController.m
    //  38_手势
    //
    //  Created by beyond on 14-9-17.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "SwipeLongPressController.h"
    
    @interface SwipeLongPressController ()
    @property (weak, nonatomic) IBOutlet UIImageView *nanaImgView;
    - (IBAction)dismiss;
    
    @end
    
    @implementation SwipeLongPressController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // 1.同意交互
        _nanaImgView.userInteractionEnabled = YES;
        
        // 2.自己定义方法,加入swipe手势
        [self addSwipe];
        
        // 3.自己定义方法,加入longPress手势
        [self addLongPress];
    }
    
    // 2.自己定义方法,加入swipe手势
    - (void)addSwipe
    {
        // 1.创建Swipe手势识别器对象,同一时候绑定监听方法(识别到了相应的手势,就会调用监听方法)
        UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiping)];
        // 设置属性:轻扫的方向
        swipe.direction = UISwipeGestureRecognizerDirectionUp;
        // 2.为nanaImgView 加入Swipe手势识别器对象
        [self.nanaImgView addGestureRecognizer:swipe];
    }
    // 3.自己定义方法,加入longPress手势
    - (void)addLongPress
    {
        // 1.创建LongPress手势识别器对象,同一时候绑定监听方法(识别到了相应的手势,就会调用监听方法)
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] init];
        [longPress addTarget:self action:@selector(longPressing)];
        
        // 设置属性:至少长按2秒,默认0.5秒
        longPress.minimumPressDuration = 2;
        // 按下之后,不松手,在能触发手势之前,可同意移动的范围,50px范围内长按有效,默认是10px
        longPress.allowableMovement = 50;
        
        // 2.为nanaImgView 加入Swipe手势识别器对象
        [self.nanaImgView addGestureRecognizer:longPress];
    }
    #define kRandomColor [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1.0]
    // 手势的监听的方法
    - (void)swiping
    {
        self.view.backgroundColor = kRandomColor;
        NSLog(@"-----swiping");
    }
    // 手势的监听的方法
    - (void)longPressing
    {
        self.view.backgroundColor = kRandomColor;
        NSLog(@"-------长按了nanaImgView");
    }
    
    
    
    - (IBAction)dismiss
    {
        [self dismissViewControllerAnimated:YES completion:nil   ];
    }
    @end
    


    Pinch和Rotation手势


    捏合(缩放)和旋转


    终于效果图:




    //
    //  PinchRotationController.m
    //  38_手势
    //
    //  Created by beyond on 14-9-17.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "PinchRotationController.h"
    
    // 手势识别器的代理方法,目的是:
    @interface PinchRotationController ()<UIGestureRecognizerDelegate>
    @property (weak, nonatomic) IBOutlet UIImageView *nanaImgView;
    - (IBAction)dismiss;
    
    @end
    
    @implementation PinchRotationController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // 同一时候加入Pinch捏合手势(缩放) 和旋转手势
        [self addPinchAndRotate];
    }
    
    
    
    #pragma mark - 缩放 + 旋转
    - (void)addPinchAndRotate
    {
        // 1.加入 Pinch捏合手势(缩放)
        [self addPinch];
        // 2.加入 旋转手势
        [self addRotate];
    }
    
    // 1.加入 Pinch捏合手势(缩放) ,缩放手势(捏合手势)
    - (void)addPinch
    {
        // 1.创建Pinch手势识别器对象,同一时候绑定监听方法(识别到了相应的手势,就会调用监听方法)
        UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinching:)];
        // 2.设置代理???
        pinch.delegate = self;
        // 3.为nanaImgView 加入Pinch手势识别器对象
        [self.nanaImgView addGestureRecognizer:pinch];
    }
    
    // 2.加入 旋转手势
    - (void)addRotate
    {
        // 1.创建Rotation手势识别器对象,同一时候绑定监听方法(识别到了相应的手势,就会调用监听方法)
        UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotating:)];
        // 2.设置代理???
        rotate.delegate = self;
        // 3.为nanaImgView 加入Rotation手势识别器对象
        [self.nanaImgView addGestureRecognizer:rotate];
    }
    #pragma mark - 重要~~~~手势的监听方法
    // Pinch捏合(缩放)
    - (void)pinching:(UIPinchGestureRecognizer *)pinch
    {
        // X Y 按比例进行缩放
        pinch.view.transform = CGAffineTransformScale(pinch.view.transform, pinch.scale, pinch.scale);
        // 每次又一次归零~~~
        pinch.scale = 1; // 这个真的非常重要!!!!!
    }
    // 旋转手势
    - (void)rotating:(UIRotationGestureRecognizer *)rotate
    {
        // 按手势识别器 的旋转角度进行旋转
        rotate.view.transform = CGAffineTransformRotate(rotate.view.transform, rotate.rotation);
        // 每次要又一次归零~~~~
        rotate.rotation = 0; // 这个非常重要!!!!!
    }
    
    #pragma mark - 手势识别器的代理方法
    /**
     *  是否同意多个手势识别器同一时候有效
     *  Simultaneously : 同一时候地
     */
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    
    #pragma mark - 连线方法
    - (IBAction)dismiss
    {
        [self dismissViewControllerAnimated:YES completion:nil   ];
    }
    @end
    






    涂鸦

    终于效果图:




    控制器

    //
    //  PaintController.m
    //  38_手势_涂鸦
    //
    //  Created by beyond on 14-9-17.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //  涂鸦控制器
    
    #import "PaintController.h"
    // 画布
    #import "Canvas.h"
    
    
    @interface PaintController ()
    // 画板
    @property (weak, nonatomic) IBOutlet Canvas *canvasView;
    
    // 清除画板
    - (IBAction)clear;
    // 撤销
    - (IBAction)undo;
    // 保存至相冊
    - (IBAction)save;
    
    @end
    
    @implementation PaintController
    
    
    
    // 清除画板
    - (IBAction)clear
    {
        [self.canvasView clear];
    }
    // 撤销
    - (IBAction)undo
    {
        [self.canvasView undo];
    }
    // 保存至相冊
    - (IBAction)save
    {
        // 1.截图
        UIImage *image = [UIImage captureWithView:self.canvasView];
        
        // 2.保存到图片,建议使用系统推荐的回调方法
        UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
    
    // 保存图片操作之后就会调用本方法
    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
    {
        if (error) { // 保存失败
            [MBProgressHUD showError:@"保存失败"];
        } else { // 保存成功
            [MBProgressHUD showSuccess:@"保存成功"];
        }
    }
    
    @end
    


    自己定义View:画布

    //
    //  Canvas.h
    //  38_手势_涂鸦
    //
    //  Created by beyond on 14-9-17.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //  画布
    
    #import <UIKit/UIKit.h>
    
    @interface Canvas : UIView
    // 清除画板
    - (void)clear;
    // 撤销上一笔画
    - (void)undo;
    @end
    


    //
    //  Canvas.m
    //  38_手势_涂鸦
    //
    //  Created by beyond on 14-9-17.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //  画布,核心代码
    
    #import "Canvas.h"
    
    @interface Canvas()
    // 存放贝塞尔路径对象数组,每一次touchBegin,相应一个新的路径
    @property (nonatomic, strong) NSMutableArray *pathArr;
    @end
    
    @implementation Canvas
    #pragma mark - 懒载入
    - (NSMutableArray *)pathArr
    {
        if (_pathArr == nil) {
            _pathArr = [NSMutableArray array];
        }
        return _pathArr;
    }
    // 清除画板
    - (void)clear
    {
        [self.pathArr removeAllObjects];
        [self setNeedsDisplay];
    }
    // 撤销上一笔画
    - (void)undo
    {
        [self.pathArr removeLastObject];
        [self setNeedsDisplay];
    }
    #pragma mark - Touch方法
    // 每一次touchBegin,相应一个新的路径对象
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 1.获得当前的触摸点
        UITouch *touch = [touches anyObject];
        CGPoint startPos = [touch locationInView:touch.view];
        
        // 2.创建一个新的路径
        UIBezierPath *currenPath = [UIBezierPath bezierPath];
        currenPath.lineCapStyle = kCGLineCapRound;
        currenPath.lineJoinStyle = kCGLineJoinRound;
        
        // 设置起点
        [currenPath moveToPoint:startPos];
        
        // 3.加入路径到数组中
        [self.pathArr addObject:currenPath];
        
        [self setNeedsDisplay];
    }
    
    // 取出最新的贝塞尔路径,加入新的点进去
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [touches anyObject];
        CGPoint pos = [touch locationInView:touch.view];
        
        UIBezierPath *currentPath = [self.pathArr lastObject];
        [currentPath addLineToPoint:pos];
        
        [self setNeedsDisplay];
    }
    
    // 抬笔时,与move一样
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self touchesMoved:touches withEvent:event];
    }
    #pragma mark - 画线
    - (void)drawRect:(CGRect)rect
    {
        [[UIColor redColor] set];
        
        for (UIBezierPath *path in self.pathArr) {
            path.lineWidth = 10;
            [path stroke];
        }
    }
    #pragma mark - 測试C画线代码
    - (void)testPath
    {
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        //    CGContextMoveToPoint(ctx, 0, 0);
        //    CGContextAddLineToPoint(ctx, 100, 100);
        //    CGContextStrokePath(ctx);
        
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathMoveToPoint(path, NULL, 0, 0);
        CGPathAddLineToPoint(path, NULL, 100, 100);
        CGContextAddPath(ctx, path);
        
        CGMutablePathRef path2 = CGPathCreateMutable();
        CGPathMoveToPoint(path2, NULL, 250, 250);
        CGPathAddLineToPoint(path2, NULL, 110, 100);
        CGContextAddPath(ctx, path2);
        
        
        CGContextStrokePath(ctx);
        
        CGPathRelease(path);
    }
    @end
    


    截图分类

    //
    //  UIImage+ScreenShot.m
    //  38_手势
    //
    //  Created by beyond on 14-9-17.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //  分类,截图
    
    #import "UIImage+ScreenShot.h"
    
    @implementation UIImage (ScreenShot)
    
    + (instancetype)captureWithView:(UIView *)view
    {
        // 1.开启上下文
        UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
        
        // 2.将控制器view的layer渲染到上下文
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
        
        // 3.取出图片
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        
        // 4.结束上下文
        UIGraphicsEndImageContext();
        
        return newImage;
    }
    @end
    


















































    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    基于WINCE.NET4.2系统的PDA使用PPC2003软件全攻略
    中文语方SQL脚本1(原创)
    debian下NAT的设置
    一个用于 MRTG 自动告警的脚本 (ZT)
    debian 4配置snmpd(有特别注意地方)
    [ZT]半小时精通正则表达式
    怎么把CSDN上的文章及图片导出到本地?
    zookeeper 简介
    Linux之搜索查找类指令
    Java之文档注释基本使用
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4669448.html
Copyright © 2011-2022 走看看