UI 触摸与手势

触摸(UITouch)

  • UITouch方法
1
2
3
4
5
6
7
8
9
10
11
// 触摸开始
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

// 触摸移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

// 触摸结束
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

// 触摸取消
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
  • 场景举例
    有时需要用户触摸某个视图移动,并且视图会跟着触摸手势轨迹的移动的时候,我们可通过触摸移动方法touchesMoved实现。
1
2
3
4
5
6
7
8
9
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@", NSStringFromSelector(_cmd)); UITouch *touch = [touches anyObject]; if (touch.view == _showView) {
// 前一个点
CGPoint previousLocation = [touch previousLocationInView:_showView]; // 当前点
CGPoint currentLocation = [touch locationInView:_showView]; // 偏移
CGPoint offset = CGPointMake(currentLocation.x - previousLocation.x,currentLocation.y - previousLocation.y); // 改变视图位置
_showView.center = CGPointMake(_showView.center.x + offset.x,_showView.center.y + offset.y); }
}

手势(UIGestureRecognizer)

简介
  • Cocoa Touch中为我们提供了便利的手势处理类:UIGestureRecognizer

  • 由UIGestureRecognizer衍生的常用子类有:
    点击手势:UITapGestureRecognizer
    缩放手势:UIPinchGestureRecognizer
    旋转手势:UIRotationGestureRecognizer
    滑动手势:UISwipeGestureRecognizer
    拖动手势:UIPanGestureRecognizer
    长按手势:UILongPressGestureRecognizer

  • 初始化手势

1
- (id)initWithTarget:(id)target action:(SEL)action;
  • 添加或移除指定视图上的手势
1
2
3
4
5
// 添加手势 
- (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer;

// 移除手势
- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer;
  • 当同一视图上存在多个手势时,会出现冲突,可以使用一个方法来避免多手势带来的冲突
1
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#import "UIGestureRecognizerViewController.h" 

#define vc_title @"Gesture"

@interface UIGestureRecognizerViewController ()

@property (nonatomic, strong)UILabel *stateLabel;
@property (nonatomic, strong)UIView *gestureView;
/**
* 初始化用户界面
*/ - (void)initializeUserInterface; /**
* 初始化手势
*/ - (void)initializeGestureRecognizer;
@end

@implementation UIGestureRecognizerViewController

- (void)viewDidLoad {
[super viewDidLoad];
[self initializeUserInterface];
[self initializeGestureRecognizer];
}

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // autolayout自动布局 [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_stateLabel]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_stateLabel)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[_stateLabel(==30)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_stateLabel)]];
}

#pragma mark - init

- (void)initializeUserInterface
{
self.view.backgroundColor = [UIColor whiteColor];
self.title = vc_title;

[self.view addSubview:self.stateLabel];
[self.view addSubview:self.gestureView];
}

- (void)initializeGestureRecognizer
{
// 1、点击手势识别器
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToGestureRecognizer:)];
// 设置点击次数
tapGesture.numberOfTapsRequired = 1;
// 设置手指数量
tapGesture.numberOfTouchesRequired = 1;
// 添加手势
[_gestureView addGestureRecognizer:tapGesture];

// 2、长按手势识别器
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToGestureRecognizer:)];
[_gestureView addGestureRecognizer:longPressGesture];

// 3、滑动手势识别器
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToGestureRecognizer:)];
// 设置滑动方向:right、left、up、down
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[_gestureView addGestureRecognizer:swipeGesture];

// 4、拖拽手势识别器
UIPanGestureRecognizer *panPress = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToGestureRecognizer:)];
[_gestureView addGestureRecognizer:panPress];

// 5、捏合手势识别器
UIPinchGestureRecognizer * pinchPress = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(respondsToGestureRecognizer:)];
[_gestureView addGestureRecognizer:pinchPress];

// 6、旋转手势识别器
UIRotationGestureRecognizer * rotationPress = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(respondsToGestureRecognizer:)];
[_gestureView addGestureRecognizer:rotationPress];
// 手势识别器冲突
[swipeGesture requireGestureRecognizerToFail:panPress];
// 如果冲突,执行后面的
}

#pragma mark - responds event

- (void)respondsToGestureRecognizer:(UIGestureRecognizer *)gesture
{
// 点击手势识别器
if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) {
UITapGestureRecognizer *tap = (UITapGestureRecognizer *)gesture;
// state 属性:获取用户手势状态
if (tap.state == UIGestureRecognizerStateBegan) {
[_stateLabel setText:@"用户开始点击"];
} else if (tap.state == UIGestureRecognizerStateEnded) {
[_stateLabel setText:@"用户点击结束"];
}
}
// 长按手势识别器
else if ([gesture isKindOfClass:[UILongPressGestureRecognizer class]]) {
UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)gesture;
if (longPress.state == UIGestureRecognizerStateBegan) {
[_stateLabel setText:@"长按手势开始"];
} else if (longPress.state == UIGestureRecognizerStateEnded) {
[_stateLabel setText:@"长按手势结束"];
}
}
// 滑动手势识别器
else if ([gesture isKindOfClass:[UISwipeGestureRecognizer class]]) {

UISwipeGestureRecognizer *swipePress = (UISwipeGestureRecognizer *)gesture;
if (swipePress.state == UIGestureRecognizerStateBegan) {
[_stateLabel setText:@"滑动手势开始"];

} else if(swipePress.state == UIGestureRecognizerStateChanged) {
[_stateLabel setText:@"滑动手势滑动中"];
}else if (swipePress.state == UIGestureRecognizerStateEnded) {
[_stateLabel setText:@"滑动手势结束"];
}

}
// 拖拽手势识别器
else if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gesture;
// 声明一个静态的变量记录拖拽视图前时的中心点
static CGPoint firstCenter;
if (pan.state == UIGestureRecognizerStateBegan) {
// 给firstCenter赋值
firstCenter = self.view.center;
[_stateLabel setText:@"拖拽手势开始"];
} else if (pan.state == UIGestureRecognizerStateChanged) {
// 获取手势在某一个视图上的移动了多少
CGPoint translation = [pan translationInView:self.view];
_gestureView.center = CGPointMake(firstCenter.x + translation.x, firstCenter.y + translation.y);
[_stateLabel setText:@"拖拽手势拖动中"];
} else if (pan.state == UIGestureRecognizerStateEnded) {
// 更新静态变量firstCenter的值,供下次识别这个手势时使用
firstCenter = _gestureView.center;
[_stateLabel setText:@"拖拽手势结束"];
}
}
// 捏合手势识别器
else if ([gesture isKindOfClass:[UIPinchGestureRecognizer class]]) {
UIPinchGestureRecognizer * pinch = (UIPinchGestureRecognizer *)gesture;
static CGFloat lastScale;
if (pinch.state == UIGestureRecognizerStateBegan) {
lastScale = pinch.scale;
[_stateLabel setText:@" 捏合手势开始"];
} else if (pinch.state == UIGestureRecognizerStateChanged) {

CGFloat changeScale = (pinch.scale - lastScale)/2 + 1;

if (_gestureView.bounds.size.width < 100) {
// 当视图<100,就不能再缩小
return;

} else {
_gestureView.transform = CGAffineTransformScale(_gestureView.transform, changeScale, changeScale);
lastScale = pinch.scale;

}
} else if (pinch.state == UIGestureRecognizerStateEnded){
lastScale = 1;
[_stateLabel setText:@" 捏合手势结束"];
}
}
// 旋转手势识别器
else if ([gesture isKindOfClass:[UIRotationGestureRecognizer class]]) {

UIRotationGestureRecognizer * rotation = (UIRotationGestureRecognizer *)gesture;
static CGFloat lastRotate;
if (rotation.state == UIGestureRecognizerStateBegan) {
lastRotate = rotation.rotation;
[_stateLabel setText:@"旋转手势开始"];
} else if (rotation.state == UIGestureRecognizerStateChanged) {
CGFloat changeRotate = rotation.rotation - lastRotate;
_gestureView.transform = CGAffineTransformRotate(_gestureView.transform, changeRotate);
lastRotate = rotation.rotation;
} else if (rotation.state) {
lastRotate = 0;
}
}
}

#pragma mark - getter

- (UILabel *)stateLabel {
if (!_stateLabel) {
_stateLabel = [[UILabel alloc] init];
_stateLabel.translatesAutoresizingMaskIntoConstraints = NO;
_stateLabel.textAlignment = NSTextAlignmentCenter;
_stateLabel.font = [UIFont systemFontOfSize:25];
}
return _stateLabel;
}

- (UIView *)gestureView {
if (!_gestureView) {
_gestureView = [[UIView alloc] init];
_gestureView.bounds = CGRectMake(0, 0, 200, 200);
_gestureView.center = self.view.center;
_gestureView.backgroundColor = [UIColor redColor];
// 开启用户交互
_gestureView.userInteractionEnabled = YES;
}
return _gestureView;
}

@end