IOS--UI--LessonTouchView 触摸事件 & 响应者链

触摸事件
一个软件 或者一个界面 对于 IOS 来说 都是触碰操作
1.创建根控制器 RootViewController 来操作
cmd+n
创建好之后 要将原有的根控制器替换
①引入头文件
②替换控制器


    RootViewController *rootVC=[[RootViewController alloc]init];
//    用 rootVC 来初始化
    self.window .rootViewController =rootVC;
     [RootViewController release];

3.首先创建我们需要的视图类
RootViewController.m 中创建:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(60, 184, 200, 200)];
    view .backgroundColor = [UIColor redColor];
    [self.view addSubview:view];
    [view release];
    }

这样我们的类就会创建好
3.今天主要是让我们的视图类 对手指的触摸发生反应 比如移动 变色 之类的
所以我们要再建一个 TouchView
cmd+n 继承 UIView;
①在TouchView. m 中 想让一个视图对触摸做出反应

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     NSLog(@"%s",__FUNCTION__);


}
// 当触摸点在视图上移动的时候 触发
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

    NSLog(@"%s",__FUNCTION__);
}
//触摸事件被意外终端的时候(比如 :电话进来)
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{

     NSLog(@"%s",__FUNCTION__);
}
//当触摸离开屏幕的时候触发
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

     NSLog(@"%s",__FUNCTION__);
}

当我们在触摸设定好的视图后 控制台就会显示出运行的代码

② 需求:当我触摸视图的时候 背景色变化
解决:当我们触摸视图的时候 就是控制台显示的是began 所以 我们将控制背景色的代码写在 began 里面 颜色可以赋死值 也可以随机色

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
  self.backgroundColor = [UIColor randomColor];
  // 这里的 self 指的就是调用了这个方法的类 你又不知道是谁会用 所以用 self 最方便
  // randomColor 是类目 完全体是:UIColor colorWithRed:COLORVALUE green:COLORVALUE blue:COLORVALUE alpha:1.0];
  //但是太长了  所以我们用类目封起来 引用头文件 就可以用了
  // 我们还想父类视图颜色变起来怎么办呢?用 superView 
   self.superview.backgroundColor = [UIColor randomColor];

    NSLog(@"%s",__FUNCTION__);


}
随机色的类目:UIColor+Random
.h 里面
#import <UIKit/UIKit.h>

@interface UIColor (Random)
+(UIColor *)randomColor;
@end
.m 里面
#import "UIColor+Random.h"
#define COLORVALUE arc4random()%256/255.0
@implementation UIColor (Random)
+(UIColor *)randomColor{
    return [UIColor colorWithRed:COLORVALUE green:COLORVALUE blue:COLORVALUE alpha:1.0];
}
@end
这里面 又有类目 又有宏 是不是感觉很厉害 都是因为程序员太懒了╮(╯▽╰)╭

注意!!:需求说的是触摸就变色 那么大王说我单击和双击 想发生不一样的改变
解决: 首先 判断 单击和双击 UITouch *touch = [touches anyObject];获取手指,这时候得到在屏幕的手指数,获取其中的任意一个,注意存放手指的是个集合,我们没有办法指定获取其中的一个,只能随机取一个,因为里面只有一个的时候,取的肯定使我们想要的


 UITouch *touch = [touches anyObject];
    if (1 == touch.tapCount) {
    tapCount是UITouch的一个属性,存放点击屏幕的次数
        //当视图识别单击操作 就延迟执行下面方法 改变颜色 等待 是否会有双击发生
        [self performSelector:@selector(changeMyselfBackgroundColor) withObject:nil afterDelay:.3];
        //changeMyselfBackgroundColor 就是我们要走的方法 在下面写出来
//        self.backgroundColor = [UIColor randomColor];

    }else if(2==touch.tapCount){
        // 当识别为双击的时候 取消之前的操作 (就是单击操作那个方法)
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(changeMyselfBackgroundColor) object:nil];
        self.superview.backgroundColor = [UIColor randomColor];
        self.backgroundColor = [UIColor randomColor];


    }
}
-(void)changeMyselfBackgroundColor{

    self.superview.backgroundColor = [UIColor randomColor];
}
这段代码的意思就是 判断摸了几次 touch.tapCount  然后 就走那个方法 这个时候要注意 你在上面的
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
  //self.backgroundColor = [UIColor randomColor];

  // self.superview.backgroundColor = [UIColor randomColor];
}

这段代码里 就要把里面的东西注掉  因为你触摸式从 began 开始的 但是你began 里面有方法 他就会直接走里面的方法 那你下面的判断就会不走
最后我们在 Controller .m 里面 创建 touchView 就可以运行了

RootViewController.m
 TouchView *touchView = [[TouchView alloc]initWithFrame:CGRectMake(60, 184, 200, 200)];
    touchView.backgroundColor = [UIColor redColor];
    [self.view addSubview:touchView];
    [touchView release];

③ 需求:我想拖动视图怎么办 让跟着我舞动起来
解决:那就是当我们触摸的时候触发效果呗
前提,在视图控制器中布局好视图
视图的拖拽最重要的是要切记,只要知道中心点center的移动距离和方向,就能算出整个视图的移动距离和方向
视图的拖拽是在移动函数中写的
注:我们用什么 就是创建什么 其他的可以不用管
同样 为了好看简洁我们的控制器 我们将MoveView 创建一个类

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    //实现
    // 1.先获得手指对象 
    UITouch *touch = [touches anyObject];
//    2.获取当前位置的的手指位置 自身视图上
    CGPoint currenPoint = [touch locationInView:self];
//    3.获取手指之前的位置
    CGPoint previousPoint = [touch previousLocationInView:self];
    // 计算移动的增量 就是让之前和之后相减
    CGFloat dx = currenPoint.x - previousPoint.x;
    CGFloat dy = currenPoint.y - previousPoint.y;
    CGPoint center = self.center;
    self.center = CGPointMake(center.x+dx, center.y+dy);

}


@end
最后我们在 Controller .m 里面 创建 touchView 就可以运行了

RootViewController.m
 MoveView *moveView = [[MoveView alloc]initWithFrame:CGRectMake(60, 184, 200, 200)];
    moveView.backgroundColor = [UIColor randomColor ];
    [self.view addSubview:moveView];
    [moveView release];

④需求:这个图片我没看清出 想放大:
解决: OK 这个就是等比缩放 不变的是中心点 我们算出放大前后的比例就可以了 同样 封装一个新的类 PinchView

在实现视图的捏合的时候要注意,这里需要用到两个手指对象,但是系统默认的是单点触摸,所以要重写init方法
PinchView.m

-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
//        IOS 支持多点触摸 但是默认只能单点触摸
        self.multipleTouchEnabled = YES;
    }return self;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    if (1 == touches.count) {
        return;
    }else{
        // 1.取出两个手指对象所在的集合  是一个数组
        NSArray *allTouch = [touches allObjects];
        //2.获取手指对象
        UITouch *touch1 = [allTouch firstObject];
        UITouch *touch2 = [allTouch lastObject];
       //获得两个手指的当前位置
        CGPoint currentPoint = [touch1 locationInView:self];
        CGPoint previousPoint = [touch2  previousLocationInView:self];
        //    4.计算当前两个点得手指距离
        CGFloat currentDistance = [self distanceFromPoint:currentPoint toPoint:previousPoint];
        //    5.获取之前两个手指的位置
        CGPoint previousFirstPoint = [touch1 previousLocationInView:self];
        CGPoint previousSecondPoint = [ touch2 previousLocationInView:self];
        //    获取两个手指之间的距离
        CGFloat previousDistance = [self distanceFromPoint:previousFirstPoint toPoint:previousSecondPoint];
        //    获取缩小的前后的比例
        CGFloat rate = currentDistance/previousDistance;
        //    缩放视图大小,但中心点不会变 这时候选择修改 Bounds 就可以
        self.bounds = CGRectMake(0, 0, self.frame.size.width*rate, self.frame.size.height*rate);

    }

}
//封装计算两个点距离的方法

-(CGFloat)distanceFromPoint :(CGPoint)fromPoint toPoint:(CGPoint)toPoint{
    CGFloat dx = fromPoint.x -toPoint.x;
    CGFloat dy = fromPoint.y - toPoint.y;
    return sqrt(dx*dx+dy*dy);

}
最后我们在 Controller .m 里面 创建 touchView 就可以运行了

RootViewController.m
 PinchView *pinchView = [[PinchView alloc]initWithFrame:CGRectMake(10, 20, 300, 528)];
    pinchView.backgroundColor = [UIColor randomColor];
    [self.view addSubview:pinchView];
    [pinchView release];


你不写最后在 controller 里面 他就找不到这个方法 我们怎么实现操作呢?

因为我们在 TouchView 里面 实现了 拖动 变色 等比缩放 所以 .m 里面的最终形态应该是这样的;

#import "TouchView.h"
#import "UIColor+Random.h"
@implementation TouchView
//如果想让一个视图 对触摸事件 做出回应
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     NSLog(@"%s",__FUNCTION__);
    self.backgroundColor = [UIColor randomColor];
    //父视图的属性
    //  给添加类目
   self.superview.backgroundColor = [UIColor randomColor];
    //调用改变中心点得方法
    [self changeMyselfCenter];

     //UITouch 点击类

}
// 当触摸点在视图上移动的时候 触发
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    if (2 ==touch.tapCount) {

    }
    NSLog(@"%s",__FUNCTION__);
}
//触摸事件被意外终端的时候(比如 :电话进来)
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{

     NSLog(@"%s",__FUNCTION__);
}
//当触摸离开屏幕的时候触发
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    //touchs 存放手指对象
  UITouch *touch = [touches anyObject];
    if (1 == touch.tapCount) {
        //当视图识别单击操作 就延迟执行下面方法 改变颜色 等待 是否会有双击发生
        [self performSelector:@selector(changeMyselfBackgroundColor) withObject:nil afterDelay:0.3];

//        self.backgroundColor = [UIColor randomColor];
    }else if(2==touch.tapCount){
        // 当识别为双击的时候 取消之前的操作 (就是单击操作那个方法)
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(changeMyselfBackgroundColor) object:nil];
        self.superview.backgroundColor = [UIColor randomColor];

    }
     NSLog(@"%s",__FUNCTION__);
}

-(void)changeMyselfCenter{
    self.center = CGPointMake(arc4random()%200+100, arc4random()%400+120);
}
-(void)changeMyselfBackgroundColor{
      self.backgroundColor = [UIColor randomColor];
}

@end

===================响应者链===================

1.有多个响应者对象组成的链(父视图子视图)
UIResponder 响应者类,iOS中所有能响应事件(触摸、晃动、远程事件)的对象都是响应者,系统定义了一个抽象的父类UIResponder来表示响应者,其子类都是响应者。
硬件检测到触摸操作,会将信息交给UIApplication,开始检测。
UIApplication -> window -> viewController -> view ->检测所有子视图,最终确认碰触位置,完成响应者链的查询过程。

2.处理触碰事件
检测到响应者后,实现touchesBegan:withEvent:等方法,即处理事件。
如果响应者没有处理事件,事件会向下传递,如果没有响应者处理,则丢弃触摸事件。
事件处理的顺序与触摸检测查询相反,触摸的子视图 -> view -> viewController -> window -> UIApplication
3.阻断响应者链,
响应者链可以被打断,无妨完成检测查询过程,视图类的属性:userInteractionEnabled,关闭后能阻断查询过程
要实现那个视图的响应,我们就要在他的.m中重写响应方法,所以一般在需要一个响应视图的时候我们会创建一个子类,这样能够在.m中写响应方法,如我们要实现UIView的一个视图的响应,我们就要建一个UIView的子类,在子类中重写方法。在重写方法的时候我们一般通过tag值来确定访问的对象。

注:有一个方法我们没有用到 就是Cancelled 后面我们会学到
1.将我们的需求选好地方创建,比如 began move
2.封装之后记得在你想使用的里面引入头文件
3.在单击双击的时候 要将之前在 began 写的变色注掉 还要注意
4.触摸事件 就是响应者链的体现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值