本章主要学习了IOS开发中的触摸手势以及图形变换的知识,其中手势包括单击、双击、长按、拖动、滑动、缩放、旋转,图形变化主要使用放射矩阵的平移、缩放和旋转。
使用手势时应该注意手势是指定到特定的视图(UIView)上的,因此一个手势只能对应一个视图(手势里面的view属性可获取其所所对应的视图),而一个View可以添加多个手势。同时,因为有的手势之间有冲突的,比如单击和双击,滑动和拖动。针对这种情形需要使用手势的依赖性特性做出区分,改特性要求特定手势失败后才触发该手势。
仿射矩阵变化应该注意到是通过视图的变化而达到显示效果的,同时还要注意到UIKit坐标和绘图坐标之间的差异。
1.手势是针对特定视图的,所以在学习过程中我都是在一个视图类里面做实验的,该类是一个UIView的子类。
2.IOS的手势分为以下几个,其分别对应一个类:
一个滑动手势的对象只支持一个方向,默认是右滑,如果想要支持四个方向,那就需要添加四个滑动手势的对象,同时通过属性direction指定。
- UITapGestureRecognizer (单击和双击,根据setNumberOfTapsRequired设置区分)
- UIPinchGestureRecognizer (缩放手势)
- UIRotationGestureRecognizer (旋转手势)
- UISwipeGestureRecognizer (滑动手势)
- UIPanGestureRecognizer (拖动手势)
- UILongPressGestureRecognizer (长安手势)
3.添加手势到视图可使用下述模板代码
/** 滑动 */ _swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)]; /** 设置手滑方向,只支持一个方向,默认是右滑 */ _swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp; [_imageView addGestureRecognizer:_swipeGestureRecognizer];注意要使的视图支持手势对象,需要启动支持手势属性,将属性userInteractionEnabled设为YES。
4.图形变化中注意到有CGAffineTransformMakeRotation和CGAffineTransformRotate类似的成对出现,其中前者有Make表示新建一个默认的矩阵,然后设置属性,而后者则是在指定的矩阵上添加属性特征,所以大部分使用类似于后者的仿射变换函数。使用例子如下
/** 设置(之前设置的其他矩阵属性重新变为默认值)矩阵 */ //CGAffineTransform t = CGAffineTransformMakeRotation(angle); /** 修改矩阵旋转属性 */ CGAffineTransform t = CGAffineTransformRotate(_imageView.transform, angle); self.imageView.transform = t;5.缩放手势(UIPinchGestureRecognizer)对象有属性scale,该属性表示缩放系数,所以在响应缩放手势的方法中可直接读取该属性设置缩放,不过使用完毕后注意将该值重置为1,如:recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale); recognizer.scale = 1;6.旋转手势(UIRotationGestureRecognizer)对象有属性rotation,该属性表示旋转属性值,所以在响应旋转手势的方法中可直接使用该属性值设置视图的旋转,注意重置0,如ecognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation); recognizer.rotation = 0;7.拖动手势(UIPanGestureRecognizer)对象通过方法translationInView获取拖动后的参数,使用例子如下CGPoint translation = [recognizer translationInView:self]; recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y); [recognizer setTranslation:CGPointZero inView:self];
//
// PickView.m
// Gesture
//
// Created by arbboter on 14/12/19.
// Copyright (c) 2014年 arbboter. All rights reserved.
//
#import "PickView.h"
@interface PickView ()
@property (nonatomic, retain) UIImageView* imageView;
@property (nonatomic, retain) UITapGestureRecognizer* tapSingleGestureRecognizer;
@property (nonatomic, retain) UITapGestureRecognizer* tapDoubleGestureRecognizer;
@property (nonatomic, retain) UIPinchGestureRecognizer* pinchGestureRecognizer;
@property (nonatomic, retain) UIRotationGestureRecognizer* rotationGestureRecognizer;
@property (nonatomic, retain) UISwipeGestureRecognizer* swipeGestureRecognizer;
@property (nonatomic, retain) UIPanGestureRecognizer* panGestureRecognizer;
@property (nonatomic, retain) UILongPressGestureRecognizer* longPressGestureRecognizer;
@end
@implementation PickView
-(void) viewImageNamed:(NSString*)imageName
{
self.layer.borderWidth = 1;
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, self.frame.size.height/4, 200, 200)];
_imageView.image = [UIImage imageNamed:imageName];
_imageView.contentMode = UIViewContentModeScaleAspectFit;
/**
*
UIViewContentModeScaleToFill, // 默认缩放方式,上下左右填充 [部分]
UIViewContentModeScaleAspectFit, // 等比例缩放,一般效果是按照小的方向缩放 [全图]
UIViewContentModeScaleAspectFill, // 等比例缩放,一般效果是按照小的方向缩放(会出现剪裁效果)[部分]
UIViewContentModeRedraw, // 视图的bounds变化时重绘
UIViewContentModeCenter, // 放在视图的bounds的中间,保持等比例 [部分]
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight
*/
[self addSubview:_imageView];
/** 单击 */
_tapSingleGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapSingleGesture:)];
[_tapSingleGestureRecognizer setNumberOfTapsRequired:1];
[_imageView addGestureRecognizer:_tapSingleGestureRecognizer];
/** 双击 */
_tapDoubleGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapDoubleGesture:)];
[_tapDoubleGestureRecognizer setNumberOfTapsRequired:2];
[_imageView addGestureRecognizer:_tapDoubleGestureRecognizer];
/** 因为双击和单击存在冲突,所以需要设定没有双击才识别为单击 */
[_tapSingleGestureRecognizer requireGestureRecognizerToFail:_tapDoubleGestureRecognizer];
/** 缩放 */
_pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(onPinchGesture:)];
[_imageView addGestureRecognizer:_pinchGestureRecognizer];
/** 旋转 */
_rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(onRotationGesture:)];
[_imageView addGestureRecognizer:_rotationGestureRecognizer];
/** 滑动 */
_swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
/** 设置手滑方向,只支持一个方向,默认是右滑 */
_swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
[_imageView addGestureRecognizer:_swipeGestureRecognizer];
/** 拖动 */
_panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPanGesture:)];
[_imageView addGestureRecognizer:_panGestureRecognizer];
/** 拖动和滑动有冲突,有限响应滑动 */
[_panGestureRecognizer requireGestureRecognizerToFail:_swipeGestureRecognizer];
/** 长按 */
_longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPressGesture:)];
[_imageView addGestureRecognizer:_longPressGestureRecognizer];
/** 图片视图启动触摸交互 */
_imageView.userInteractionEnabled = YES;
}
-(void) viewRotate:(CGFloat)angle
{
/** 设置(之前设置的其他矩阵属性重新变为默认值)矩阵 */
//CGAffineTransform t = CGAffineTransformMakeRotation(angle);
/** 修改矩阵旋转属性 */
CGAffineTransform t = CGAffineTransformRotate(_imageView.transform, angle);
self.imageView.transform = t;
}
-(void) viewTranslationX:(CGFloat)x Y:(CGFloat)y
{
/** 修改矩阵平移属性 */
CGAffineTransform t = CGAffineTransformTranslate(_imageView.transform, x, y);
self.imageView.transform = t;
}
-(void) viewScaleX:(CGFloat)x Y:(CGFloat)y
{
/** 修改矩阵缩放属性 */
CGAffineTransform t = CGAffineTransformScale(_imageView.transform, x, y);
self.imageView.transform = t;
}
#pragma 响应手势
- (void)onTapSingleGesture:(UITapGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
/** do nothing */
}
- (void)onTapDoubleGesture:(UITapGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
CGFloat x = self.superview.frame.size.width/_imageView.frame.size.width;
CGFloat y = self.superview.frame.size.height/_imageView.frame.size.height;
[self viewTranslationX:self.superview.frame.size.width-self.frame.size.width Y:0];
NSLog(@"%.2f %.2f", _imageView.center.x, _imageView.center.y);
// 缩放
if(x==1)
{
[self viewScaleX:0.5 Y:0.5];
}
// 放大
else
{
x = x > y ? y : x;
[self viewScaleX:x Y:x];
}
/** 左边界对齐 */
_imageView.center = CGPointMake(_imageView.frame.size.width/2, _imageView.frame.size.height/2 + self.superview.frame.size.height/4);
x = _imageView.frame.origin.x;
[self viewTranslationX:-x Y:0];
}
- (void)onPinchGesture:(UIPinchGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
/** 缩放图片 */
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1;
}
- (void)onRotationGesture:(UIRotationGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
/** 旋转 */
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
recognizer.rotation = 0;
}
- (void)onSwipeGesture:(UISwipeGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
/** 上滑修改父视图背景色 */
if(recognizer.direction == UISwipeGestureRecognizerDirectionUp)
{
CGFloat color[3] = {0};
color[0] = (arc4random()%50 + 1)/100.0;
color[1] = (arc4random()%50 + 1)/100.0;
color[2] = 1 - color[0] - color[1];
self.superview.backgroundColor = [UIColor colorWithRed:color[0] green:color[1] blue:color[2] alpha:1.0];
}
}
- (void)onPanGesture:(UIPanGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
/** 拖动图片 */
CGPoint translation = [recognizer translationInView:self];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointZero inView:self];
}
- (void)onLongPressGesture:(UILongPressGestureRecognizer*) recognizer
{
NSLog(@"%s", __FUNCTION__);
/** 防止同一时间多次调用 */
if(recognizer.state == UIGestureRecognizerStateBegan)
{
/** 弹出编辑选项 */
UIActionSheet* action = [[UIActionSheet alloc] initWithTitle:@"Edit Options" delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Show details" otherButtonTitles:@"Delete", @"Modify", @"Send", nil];
[action showInView:self];
[action release];
}
}
-(void) dealloc
{
[_imageView release];
[self removeGestureRecognizer:_tapSingleGestureRecognizer];
[self removeGestureRecognizer:_tapDoubleGestureRecognizer];
[self removeGestureRecognizer:_pinchGestureRecognizer];
[self removeGestureRecognizer:_rotationGestureRecognizer];
[self removeGestureRecognizer:_swipeGestureRecognizer];
[self removeGestureRecognizer:_panGestureRecognizer];
[self removeGestureRecognizer:_longPressGestureRecognizer];
[_tapSingleGestureRecognizer release];
[_tapDoubleGestureRecognizer release];
[_pinchGestureRecognizer release];
[_rotationGestureRecognizer release];
[_swipeGestureRecognizer release];
[_panGestureRecognizer release];
[_longPressGestureRecognizer release];
[super dealloc];
}
@end
触摸手势以及图形变换(UIGestureRecognizer, CGAffineTransform)
原文:http://blog.csdn.net/arbboter/article/details/42029491