手势---iOS笔记摘录
2018-07-27 本文已影响0人
平安喜乐698
目录
1. 系统自带手势
2. 自定义手势
3. 手势基类
注意:
UIImageView 和 UILabel 是少数几个不可交互的控件
需要设置userInteractionEnabled为true,否则不允许交互。
1. 系统自带手势
- 单击手势 UITapGestureRecognizer
UITapGestureRecognizer *tapG=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
tapG.numberOfTapsRequired=1; // 点击次数(默认:1)
tapG.numberOfTouchesRequired=1; // 点击手指数(默认:1)
[imgV1 addGestureRecognizer:tapG]; // imgV 必须设置为可交互
-(void)handleTap:(UITapGestureRecognizer *)tapG{
//
UIImageView *imgV=(UIImageView *)tapG.view;
}
- 缩放手势 UIPinchGestureRecognizer
// 缩放手势
UIPinchGestureRecognizer *pinchG=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
[pinchG setScale:0.5]; // 缩放比例
// pinchG.velocity(readOnly)
[[UIImageView new]addGestureRecognizer:pinchG];
-(void)handlePinch:(UIPinchGestureRecognizer *)pinchG{
//
UIImageView *imgV=(UIImageView *)pinchG.view;
// pinchG.scale
}
3.旋转手势 UIRotationGestureRecognizer
// 旋转手势
UIRotationGestureRecognizer *roteG=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(handleRote:)];
[roteG setRotation:M_PI_2]; // 旋转角度
// roteG.velocity
[[UIImageView new]addGestureRecognizer:roteG];
-(void)handleRote:(UIRotationGestureRecognizer *)roteG{
//
UIImageView *imgV=(UIImageView *)roteG.view;
// roteG.rotation
}
4.扫动手势 UISwipeGestureRecognizer
// 扫动手势
UISwipeGestureRecognizer *swipeG=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipe:)];
swipeG.numberOfTouchesRequired=1; // 默认:1
swipeG.direction=UISwipeGestureRecognizerDirectionLeft; // 如果多个方向,则添加多个手势
[[UIImageView new]addGestureRecognizer:swipeG];
-(void)handleSwipe:(UISwipeGestureRecognizer *)swipeG{
//
UIImageView *imgV=(UIImageView *)swipeG.view;
}
- 拖动手势 UIPanGestureRecognizer
// 拖动手势
UIPanGestureRecognizer *panG=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
[panG setMaximumNumberOfTouches:2]; // 最小手指数
[panG setMinimumNumberOfTouches:1]; // 最大手指数
[[UIImageView new]addGestureRecognizer:panG];
-(void)handlePan:(UIPanGestureRecognizer *)panG{
//
UIButton *itemButton=(UIButton *)panG.view;
CGPoint transP=[panG translationInView:self];
NSLog(@"%f %f",transP.x,transP.y);
//
if(transP.x>0&&transP.x<294-95){
[UIView animateWithDuration:0.1 animations:^{
[itemButton setTransform:CGAffineTransformMakeTranslation(transP.x, 0)];
}];
}else if(transP.x>=294){
[self.subject sendNext:@(100)];
}
//
if(panG.state==UIGestureRecognizerStateEnded){
[UIView animateWithDuration:0.1 animations:^{
[itemButton setTransform:CGAffineTransformIdentity];
}];
}
// [panG setTranslation:CGPointZero inView:self.view]; // reset
}
- 长按手势 UILongPressGestureRecognizer
// 长按手势
UILongPressGestureRecognizer *longPressG=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongPress:)];
longPressG.numberOfTouchesRequired=1; // 手指数(默认:1)
longPressG.numberOfTapsRequired=1; // 点击数(默认:0)
longPressG.minimumPressDuration=1; // 最小的长按时间(默认:0.5)
longPressG.allowableMovement=10; // 最大的移动距离(默认:10ps)
[[UIImageView new]addGestureRecognizer:longPressG];
-(void)handleLongPress:(UIPanGestureRecognizer *)longPressG{
//
UIImageView *imgV=(UIImageView *)longPressG.view;
}
2. 自定义手势
#import <UIKit/UIKit.h>
@interface CustomGestureRecognizer : UIGestureRecognizer
@end
#import "CustomGestureRecognizer.h"
#import <UIkit/UIGestureRecognizerSubclass.h>
@implementation CustomGestureRecognizer
-(instancetype)initWithTarget:(id)target action:(SEL)action{
return [super initWithTarget:target action:action];
}
// 开始触摸时调用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸移动时调用
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸结束时调用
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸取消时调用
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
@end
3. 手势基类
UIGestureRecognizer : NSObject
所有手势的基类,通常不直接使用
//
UIGestureRecognizer *g=[[UIGestureRecognizer alloc]initWithTarget:self action:@selector(handleG)];
// 添加targetAction
[g addTarget:OtherVC action:@selector(handleG)];
// 移除targetAction
[g removeTarget:OtherVC action:@selector(handleG)];
// 手势的当前状态(readOnly)
UIGestureRecognizerState state=g.state;
// 获取 手势操作的View(readonly)
UIView *view=g.view;
// 获取 手指数(readonly)
NSUInteger numberOfTouches=g.numberOfTouches;
// 设置 是否可用(默认:true)
[g setEnabled:true];
// 获取 是否可用
BOOL isEnabled=g.isEnabled;
// 设置 手势名
[g setName:@""];
// 获取 手势名
NSString *name=g.name;
// 获取 指定触摸点的坐标
CGPoint touchPoint=[g locationOfTouch:0 inView:g.view];
// 获取 触摸点的坐标
CGPoint touchPoint2=[g locationInView:g.view];
// 当两个手势有【冲突】时,手势1只会在手势2失败时才会有效
[g1 requireGestureRecognizerToFail:g2];
// 设置 是否同时考虑不同手势(true会忽略不同手势)
[g setRequiresExclusiveTouchType:true];
/*
手势识别和触摸事件是两个独立的事,只是可以通过以下3个属性互相影响
在默认情况下(即这3个属性都处于默认值的情况下),如果触摸window,首先由window上最先符合条件的控件(该控件记为hit-test view)接收到该touch并触发触摸事件touchesBegan。同时如果某个控件的手势识别器接收到了该touch,就会进行识别。手势识别成功之后发送触摸事件touchesCancelled给hit-testview,hit-test view不再响应touch。
*/
// 默认为YES,这种情况下当手势识别器识别到touch之后,会发送touchesCancelled给hit-testview以取消hit-test view对touch的响应,这个时候只有手势识别器响应touch。当设置成NO时,手势识别器识别到touch之后不会发送touchesCancelled给hit-test,这个时候手势识别器和hit-test view均响应touch。
[g setCancelsTouchesInView:true];
// 默认是NO,这种情况下当发生一个touch时,手势识别器先捕捉到到touch,然后发给hit-testview,两者各自做出响应。如果设置为YES,手势识别器在识别的过程中(注意是识别过程),不会将touch发给hit-test view,即hit-testview不会有任何触摸事件。只有在识别失败之后才会将touch发给hit-testview,这种情况下hit-test view的响应会延迟约0.15ms。
[g setDelaysTouchesBegan:true];
// 默认为YES。这种情况下发生一个touch时,在手势识别成功后,发送给touchesCancelled消息给hit-testview,手势识别失败时,会延迟大概0.15ms,期间没有接收到别的touch才会发送touchesEnded。如果设置为NO,则不会延迟,即会立即发送touchesEnded以结束当前触摸。
[g setDelaysTouchesEnded:true];
// 设置 允许触摸的类型
[g setAllowedTouchTypes:@[[NSNumber numberWithInt:0]]];
// 设置 允许按压的类型
[g setAllowedPressTypes:@[[NSNumber numberWithInt:0]]];
dele
// dele<UIGestureRecognizerDelegate>
[g setDelegate:self];
#pragma mark dele -UIGestureRecognizerDelegate
/*
是否允许手势
*/
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
return true;
}
// 解决有水平方向滚动的ScrollView时边缘返回手势失效的问题
// 是否支持多手势(默认:false,识别到第一个手势则停止识别第二个手势)(true,则识别到第一个手势,还会去识别第二个手势)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
// 当第一个手势和第二个手势发生冲突时,第二个失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
}
// 当第一个手势和第二个手势发生冲突时,第一个失效
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return true;
}
// 是否允许 手势识别(默认:true)
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return false; // 禁止识别
}
// 开始识别手势时调用(可用于:控件某范围有效)
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
return true;
}
UIViewController 或 UIView 中可覆写
// UIViewController:UIResponder
// 开始触摸
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸后移动
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸结束
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸取消
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
获取到侧滑手势(侧滑手势继承于:UIPanGestureRecognizer)
// 获取到侧滑手势
NSArray *gestureArray = self.navigationController.view.gestureRecognizers;
for (UIGestureRecognizer *gesture in gestureArray) {
if ([gesture isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
}
}