您的位置:首页 > 移动开发 > IOS开发

IOS基础学习日志(四)手势与触摸

2013-12-19 17:39 351 查看
  IOS基础学习日志(四)
     
     今天我们主要学习了IOS手势与触摸相关的属性、定义、声明及操作,如下便是我们今天所学内容。
本章要点:
1、事件产生与分发
2、触摸
3、手势
4、手势识别器
 触摸事件
Phone OS中的触摸事件基于多点触摸模型。
iPhone OS将一个或多个和屏幕接触的手指识别为多点触摸序列的一部分,该序列从第一个手指碰到屏幕开始,直到最后一个手指离开屏幕结束。
应用程序通常将特定组合的触摸识别为手势,并以用户直觉的方式来进行响应,比如对收缩双指距离的手势,程序的响应是缩小显示的内容;对轻拂屏幕的手势,则响应为滚动显示内容。
很多UIKit类对多点触摸事件的处理方式不同于它的对象实例,特别是像UIButtonUISlider这样的UIControl的子类。这些子类的对象—被称为控件对象—只接收特定类型的手势,比如触击或向特定方向拖拽。控件对象在正确配置之后,会在某种手势发生后将动作消息发送给目标对象。其它的UIKit类则在其它的上下文中处理手势,比如UIScrollView可以为表格视图和具有很大内容区域的文本视图提供滚动行为。
事件和触摸
在iPhone OS中,触摸动作是指手指碰到屏幕或在屏幕上移动,它是一个多点触摸序列的一部分。
事件是当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对象。事件对象为一个多点触摸序列中所有触摸动作提供一个快照,其中最重要的是特定视图中新发生或有变化的触摸动作。
一个多点触摸序列从第一个手指碰到屏幕开始,其它手指随后也可能触碰屏幕,所有手指都可能在屏幕上移动。当最后一个手指离开屏幕时,序列就结束了。在触摸的每个阶段,应用程序都会收到事件对象。
触摸信息有时间和空间两方面,时间方面的信息称为阶段(phrase),表示触摸是否刚刚开始、是否正在移动或处于静止状态,以及何时结束—也就是手指何时从屏幕举起。触摸信息还包括当前在视图或窗口中的位置信息,以及之前的位置信息(如果有的话)。
当一个手指接触屏幕时,触摸就和某个窗口或视图关联在一起,这个关联在事件的整个生命周期都会得到维护。如果有多个触摸同时发生,则只有和同一个视图相关联的触摸会被一起处理。类似地,如果两个触摸事件发生的间隔时间很短,也只有当它们和同一个视图相关联时,才会被处理为多触击事件。
1、事件产生与分发:
-术语
-触摸事件:
IOS中的触摸事件,基于多点触摸模型。
-多点触摸序列:
一个或多个接触屏幕的手指,识别为多点触摸序列的一部分。
从第一个手指碰到屏幕开始,直到最后一个手指离开屏幕结束。
-Touch是指手指放在屏幕上。
-触摸数量等于手指的数量。
-手指触摸屏幕、立即离开,则发出tap。
-检测到多点触摸,轻击次数置为1。

-手势:
UITouch:一个人触摸
UIEvent:一个事件



2、-UIEvent和UITouch的关系:
一个UITouch对象表示一个触摸,一个UIEvent对象表示一个事件。事件对象中包含与当前多点触摸序列相对应的所有触摸对象,还可以提供与特定视图或窗口相关联的触摸对象(参见图3-2)。在一个触摸序列发生的过程中,对应于特定手指的触摸对象是持久的,在跟踪手指运动的过程中,UIKit会对其进行修改。发生改变的触摸属性变量有触摸阶段、触摸在视图中的位置、发生变化之前的位置、以及时间戳。事件处理代码通过检查这些属性的值来确定如何响应事件。
-响应者链:
第一响应者是正在交互的对象。
第一响应者不处理事件,事件会按照响应者链逐级发送。
事件最终发送到UIApplication,若不处理,则被丢弃。
3、-事件处理函数:
touchesBegan:withEven:
当用户开始触摸屏幕时,在事件的开始阶段被调用。
touchesMoved:withEvent:
处理手指的移动。
touchesEnded:withEvent:
结束触摸过程时调用。
touchesCancelled:withEvent:
触摸事件被系统事件(呼入电话等)中断时调用。
4、-实现触摸处理
新建单视图工程(TouchExplorer)实现触摸处理。
ViewController.h文件
@interface ViewController:UIViewController
{
UILabel *messageLabel;  //显示触摸过程状态
UILabel *tapsLabel;   //显示连击次数
}
@property (nonatomic,retain) IBOutlet UILabel *messageLabel;
@property (nonatomic,retain) IBOutlet UILabel *tapsLabel;
(void) updateLabelsFromTouches:(NSSet*)touches;  //刷新标签                                                                  
 
@end
xib文件配置
在界面上布置两个标签,分别与messageLabel和tapsLabel连接。
点击View图标,使Utilities下View中的UserInteraction处于选中状态,即开启视图交互。
5、ViewController.m文件
@implementation ViewController
//完成合成存储器
@synthesize messageLabel;
@synthesize tapsLabel;
//更新连击次数标签
(void) updareLabelsFromTouches:(NSSet *)touches
{
//获取连击次数
NSInteger numTaps = [[touches anyObject]tapCount];
//格式化字符串
NSString *tapsMessage = [[[NSString alloc]initWithFormat:@“%d taps detected”,numTaps]autorelease];
tapsLabel.text = tapsMessage; //设置显示文本
}
//触摸开始时回调函数
(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
messageLabel.text = @“Touches Began”;
[self updateLabelsFromTouches:touches];
NSLog(@“touch event in began is:%@”,event);
}
//触摸移动时回调函数
(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
messageLabel.text = @“Touches Moved”;
[self updateLabelsFromTouches:touches];
NSLog(@“touch event in began is ::%@”,event);
}
//触摸结束时回调函数
(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
messageLabel.text = @“Touches Ended”;
[self updateLabelsFromTouches:touches];
NSLog(@“touch event in began is :::%@”, event);
}
//触摸被系统时间中断时回调函数
(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
messageLabel.text = @“Touches Cancelled”;
[self updateLabelsFromTouches:touches];
NSLog(@“touch event in began is ::::%@”,event);

}
我们在这四个方法中都设置了messageLabel,以便可以看到每个方法调用的时间。另外,每个方法都调用了updateLabelsFromTouches:方法,从其中一个动作获得连击计数。
6、相关代码:
首先创建一个空的项目:
1、在AppDelegate.h文件中
#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end
2、在AppDelegate.m文件中
#import "AppDelegate.h"
#import "BoTouchView.h"

@implementation AppDelegate

- (void)dealloc
{
    [_window release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    self.window.backgroundColor = [UIColor whiteColor];
    //创建一个子视图
    BoTouchView *pView = [[BoTouchView alloc]initWithFrame:CGRectMake(0, 10, 320, 450)];
    //设置下视图的背景色
    pView.backgroundColor = [UIColor redColor];
    //将视图直接添加在窗口中
    [self.window addSubview:pView];
    [pView release];
    
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"触摸");

}

- (void)applicationWillResignActive:(UIApplication *)application
{
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
}

- (void)applicationWillTerminate:(UIApplication *)application
{
}

@end
然后创建一个UIView项目,不带NIB文件
3、在BoTouchView.h文件中
#import <UIKit/UIKit.h>

@interface BoTouchView : UIView
{
    float _lastDis;

}

@end
4、在BoTouchView.m文件中
#import "BoTouchView.h"

@implementation BoTouchView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        //开启多点触摸
        self.multipleTouchEnabled = YES;
        self.userInteractionEnabled = YES;  
    }
    return self;
}
//触摸开始的时候调用
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchBegan");
    //使下一级视图获得响应
    [self.nextResponder touchesBegan:touches withEvent:event];
    //获取任意一个touch对象
    UITouch *pTouch = [touches anyObject];
    //获取对象在坐标系中的点
    CGPoint point = [pTouch locationInView:self];
    NSLog(@"%@",NSStringFromCGPoint(point));
    //单击和双击两个点
    NSUInteger tapCount = [pTouch tapCount];
    NSLog(@"tapCount:%d",tapCount);
    if (tapCount == 1)
    {
        [self performSelector:@selector(singleTouch:) withObject:nil afterDelay:0.2];
    }
    else if(tapCount == 2)
    {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTouch:) object:nil];
        [self doubleTouch:nil];
        }
    //获取所有触摸对象
    NSArray *pArr = [touches allObjects];
    //分别取出两个touch对象
    UITouch *pTouch1 = [pArr objectAtIndex:0];
    UITouch *pTouch2 = [pArr objectAtIndex:1];
    //获取两个touch对象的坐标点
    CGPoint point1 = [pTouch1 locationInView:self];
    CGPoint point2 = [pTouch2 locationInView:self];
    //通过自己封装的方法获取两个点之间的距离
    double distance = [self distanceOfPoint:point1 withPoint:point2];
    NSLog(@"distance = %.2f",distance);
    
    if ((distance - _lastDis) > 0)
    {
        NSLog(@"放大");
    }
    else
    {
        NSLog(@"缩小");
    }
    _lastDis = distance;
}

- (void)singleTouch:(id)sender
{
    NSLog(@"单击");
}

- (void)doubleTouch:(id)sender
{
    NSLog(@"双击");
}

//计算两个点之间距离
- (double)distanceOfPoint:(CGPoint)point1 withPoint:(CGPoint)point2
{
    double num1 = pow(point1.x - point2.x, 2);
    double num2 = pow(point1.y - point2.y, 2);
    double distance = sqrt(num1 + num2);
    return distance;

}
//触摸移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchMoved");
    //获取所有触摸对象
    NSArray *pArr = [touches allObjects];
    //分别取出两个touch对象
    UITouch *pTouch1 = [pArr objectAtIndex:0];
    UITouch *pTouch2 = [pArr objectAtIndex:1];
    //获取两个touch对象的坐标点
    CGPoint point1 = [pTouch1 locationInView:self];
    CGPoint point2 = [pTouch2 locationInView:self];
    //通过自己封装的方法获取两个点之间的距离
    double distance = [self distanceOfPoint:point1 withPoint:point2];
    NSLog(@"distance = %.2f",distance);
    
    if ((distance - _lastDis) > 0)
    {
        NSLog(@"放大");
    }
    else
    {
        NSLog(@"缩小");
    }
    _lastDis = distance;
}
//手指离开屏幕(触摸结束)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchEnd");
}
//触摸事件被打断
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchCancel");
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios手势与触摸