iOS中的四中触摸事件的详解 - 平移- 捏合 - 滑动(TouchesBegan,touchesMoved,touchesEnded,touchesCancelled)

RootViewController

#import "RootViewController.h"
#import "TouchView.h"
#import "PanView.h"
#import "PinchView.h"
@interface RootViewController ()

@end

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

//    TouchView *greenView = [[TouchView alloc] initWithFrame:CGRectMake(60, 184, 200, 200)];
//    greenView.layer.cornerRadius = greenView.frame.size.width/2;
//    greenView.backgroundColor = [UIColor greenColor];
//
//    [self.view addSubview:greenView];
//    [greenView release];
//    PanView *greenView = [[PanView alloc] initWithFrame:CGRectMake(60, 184, 200, 200)];
//    greenView.layer.cornerRadius = greenView.frame.size.width/2;
//    greenView.backgroundColor = [UIColor greenColor];
//
//    [self.view addSubview:greenView];
//    [greenView release];
    PinchView *redView = [[PinchView alloc] initWithFrame:CGRectMake(20, 40, 280, 500)];
    redView.backgroundColor = [UIColor redColor];

    [self.view addSubview:redView];
    [redView release];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  UIView *view = self.view.subviews[0];
    view.backgroundColor = [UIColor redColor];
}
@end

TouchView.m

#import "TouchView.h"
#import "UIColor+Creat.h"
@implementation TouchView

/*
 为什么定义UIView的子类?是因为当我们想让Uiview响应触摸事件的话,需要让它的.m文件中实现几个方法,UIView不能在其.m文件中实现这几个方法,因此需要定义UIView的子类

 如果想让一个视图多个触摸事件作出响应,需要实现依稀几个能够响应触摸事件的方法

*/

/**刚开始触摸的时候触发(手指刚碰到视图)*/
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    //touches 存储手指点击对象,对应的类是UITouch
    //1.获取手指点击的点
    UITouch *touch = [touches anyObject]; // 从集合中快速去除点击的对象

    //2.获取点击的次数
    if (1 == touch.tapCount) {
        //当识别是单击操作是,延迟执行,看是否是双击操作
        [self performSelector:@selector(changeSelfColor) withObject:nil afterDelay:0.3];
        //[self changeSelfColor];
    }else if(2 == touch.tapCount){
        //当识别是双击操作时,取消单击操作
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(changeSelfColor) object:nil];

        [self changeSupColor];
    }
}
//当手指在视图内移动的时候触发(前提是手指还未离开视图)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
          NSLog(@"%s,%d", __FUNCTION__,__LINE__);

}
//当手机离开视图时,即触摸结束.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//     NSLog(@"%s,%d", __FUNCTION__,__LINE__);
//    [self changeSupColor];
//    [self changeSelfFrame];
}
//当触摸取消时触发(触发被意外中断,比如有电话接入)
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
     NSLog(@"%s,%d", __FUNCTION__,__LINE__);
}
//修改自身视图颜色
- (void)changeSelfColor{
    self.backgroundColor = [UIColor randomeColor];
}
//修改父视图颜色
- (void)changeSupColor{
    self.superview.backgroundColor = [UIColor randomeColor];
}
//修改自身位置
- (void)changeSelfFrame
{
    self.center = CGPointMake(arc4random() % 101 + 100, arc4random() % 301 + 100);
}
//实现单击,双击
@end

PanView.m

#import "PanView.h"

@implementation PanView

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    //1.获取手指对象
    UITouch *touch = [touches anyObject];
    //2.获取手指当前位置
   CGPoint currentPoint = [touch locationInView:self];
    //3.获取手指之前的位置
    CGPoint previousPoint = [touch previousLocationInView:self];

    //4.计算移动的增量
    CGFloat dx = currentPoint.x - previousPoint.x;
    CGFloat dy = currentPoint.y - previousPoint.y;
    //修改视图位置
    self.center = CGPointMake(self.center.x + dx, self.center.y + dy);
}
@end

PinchView.m

#import "PinchView.h"

@implementation PinchView

- (instancetype)initWithFrame:(CGRect)frame
{
    if(self = [super initWithFrame:frame])
    {
        //iOS 支持多点触摸,只不过默认的是单点触摸
        self.multipleTouchEnabled = YES;
    }
    return self;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

    if (1 == [touches count]) {
        return; // 如果触摸视图只有一点,则不捏合
    }
    //1.获取手指对象
    NSArray *allTouch = [touches allObjects];
    //不用下标的好处,不会造成程序的崩溃(数组下标越界)
    UITouch *firstTouch = [allTouch firstObject];
    UITouch *secondTouch = [allTouch lastObject];

    //2获取两个手指对象当前位置
    CGPoint currentFirstPoint = [firstTouch locationInView:self];
    CGPoint currentSecondPoint = [secondTouch locationInView:self];
    //3.获取之前的手指的位置

    CGPoint previousFirstPoint = [firstTouch previousLocationInView:self];
    CGPoint previousSecondPoint = [secondTouch previousLocationInView:self];

    //4.计算当前两个手指的距离
    CGFloat currentDistance = [self distanceFromPoint:currentFirstPoint toPoint:currentSecondPoint];
    //5.计算捏合前两个手指的距离
    CGFloat previousDistance = [self distanceFromPoint:previousFirstPoint toPoint:previousSecondPoint];

    //6.求出牛和前后两个捏合的比例
    CGFloat rate = currentDistance / previousDistance;

    //7.缩放如果视图大小变化,并且想保持中心点不变,修改bounds即可
    self.bounds = CGRectMake(0, 0, self.bounds.size.width * rate, self.bounds.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);

}
@end
时间: 2024-10-02 02:03:41

iOS中的四中触摸事件的详解 - 平移- 捏合 - 滑动(TouchesBegan,touchesMoved,touchesEnded,touchesCancelled)的相关文章

Android ViewGroup触摸事件拦截详解

前言 在自定义ViewGroup中,有时候需要实现触摸事件拦截,比如ListView下拉刷新就是典型的触摸事件拦截的例子.触摸事件拦截就是在触摸事件被parent view拦截,而不会分发给其child,即使触摸发生在该child身上.被拦截的事件会转到parent view的onTouchEvent方法中进行处理.但是这个交互过程还是挺复杂的,有多种情况,今天我们就来分析一下吧.这篇分析文章已经放了一段时间了,如果有任何问题请高人指出. 触摸事件的分发 简单来说触摸事件的分发会经过这么几个顺序

Spring 4.2框架中注释驱动的事件监听器详解

事件交互已经成为很多应用程序不可或缺的一部分,spring框架提供了一个完整的基础设施来处理瞬时事件.下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器. 1.早期的方式 在早期,组件要从Spring事件获知自定义域事件中获取通知,那么组件必须实现ApplicationListener接口并覆写onApplicationEvent方法. @Component class OldWayBlogModifiedEventListener implements ApplicationLi

Spring 框架中注释驱动的事件监听器详解

事件交互已经成为很多应用程序不可或缺的一部分,Spring框架提供了一个完整的基础设施来处理瞬时事件.下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器. 1.早期的方式 在早期,组件要从Spring事件获知自定义域事件中获取通知,那么组件必须实现ApplicationListener接口并覆写onApplicationEvent方法. @Component class OldWayBlogModifiedEventListener implements ApplicationLi

iOS中 HTTP/Socket/TCP/IP通信协议详解

// OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 // 3. 会话层 // 4. 传输层 // 5. 网络层 // 6. 数据链接层 // 7. 物理层 // TCP/IP, 由美国国防部制定 // 1. 应用层, HTTP, FTP, SMTP, DNS // 2. 传输层, TCP, UDP // 3. 网络层, IP // 4. 链路层, ARP, RARP // HTTP(短连接) // 1. 建立链接, 三次握手 // 2. 断开

iOS中 HTTP/Socket/TCP/IP通信协议详解 韩俊强的博客

每日更新关注:http://weibo.com/hanjunqiang  新浪微博 简单介绍: // OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 // 3. 会话层 // 4. 传输层 // 5. 网络层 // 6. 数据链接层 // 7. 物理层 // TCP/IP, 由美国国防部制定 // 1. 应用层, HTTP, FTP, SMTP, DNS // 2. 传输层, TCP, UDP // 3. 网络层, IP // 4. 链路层,

iOS中 本地通知/本地通知详解 韩俊强的博客

布局如下:(重点讲本地通知) 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 Notification是智能手机应用编程中非常常用的一种传递信息的机制,而且可以非常好的节省资源,不用消耗资源来不停地检查信息状态(Pooling),在iOS下应用分为两种不同的Notification种类,本地和远程.本地的Notification由iOS下NotificationManager统一管理,只需要将封装好的本地Notification对象加入到系统Notificat

ios 中__bridge,__bridge_transfer和__bridge_retained详解

转载自:http://www.cocoachina.com/industry/20130411/5975.html Objective-C和Core Foundation 对象相互转换的内存管理总结 发布于:2013-04-11 13:37阅读数:4109 iOS允许Objective-C 和 Core Foundation 对象之间可以轻松的转换,拿 NSString 和 CFStringRef 来说,直接转换毫无压力: [cpp] view plaincopyprint? 01. CFStr

IOS中Key-Value Coding (KVC)的使用详解

kvc,键值编码,是一个非正式的协议,它提供一种机制来间接访问对象的属性.直接访问对象是通过调用访问器的方法实现,而kvc不需要调用访问器的设置和获取方法,可以直接访问对象的属性. 下面介绍一下kvc的用法: 1.对属性赋值 kvc是通过键值对的方式对属性设置值,提供了下面的方法,相当于访问器中的set方法.value为要设置的值,key是字符串,字符串中内容为为属性的名称 - (void)setValue:(id)value forKey:(NSString *)key; - (void)se

IOS开发—事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

触摸事件 在用户使用app过程中,会产生各种各样的事件 一.iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件.我们称之为“响应者对象” UIApplication.UIViewController.UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件 二.UIResponder UIResponder内部提供了以下方法来处理事件触摸事件- (v