UIScrollView中的手势
UIScrollView自带了两个手势,分别为:
UIPanGestureRecognizer
UIPinchGestureRecognizer
他们都是readonly的.
监听UIPanGestureRecognizer
手势是UIPanGestureRecognizer的属性,我们可以使用KVO来进行监听.
#import "RootViewController.h"#define WIDTH self.view.frame.size.width#define HEIGHT self.view.frame.size.height@interface RootViewController ()@property (nonatomic, strong) UIScrollView *scrollView;@end@implementation RootViewController- (void)viewDidLoad{ [super viewDidLoad]; _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT)]; _scrollView.contentSize = CGSizeMake(WIDTH, HEIGHT * 3); [self.view addSubview:_scrollView]; [_scrollView addObserver:self forKeyPath:@"panGestureRecognizer.state" options:NSKeyValueObservingOptionNew context:nil];}-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ // 监听pan手势开始 if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateBegan) { NSLog(@"UIGestureRecognizerStateBegan"); } // 监听pan手势值改变 if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateChanged) { NSLog(@"UIGestureRecognizerStateChanged"); } // 监听pan手势结束 if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded) { NSLog(@"UIGestureRecognizerStateEnded"); }}- (void)dealloc{ [_scrollView removeObserver:self forKeyPath:@"panGestureRecognizer.state"];}@end
核心代码如下:
本人在测试的时候发现,一个完整的手势事件,一般情况下,手势值的改变是会执行多次的,而UIScrollview中的pan手势处理过后,手势开始,手势值改变以及手势结束,均只执行一回.
添加UISwipeGestureRecognizer手势
我们可以给UIScrollview添加UISwipeGestureRecognizer手势来判断是往哪个方向轻轻滑动了.
#import "RootViewController.h"#import "GestureView.h"@interface RootViewController ()@end@implementation RootViewController- (void)viewDidLoad{ [super viewDidLoad]; #define WIDTH self.view.frame.size.width#define HEIGHT self.view.frame.size.height UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; scrollView.backgroundColor = [UIColor grayColor]; scrollView.contentSize = CGSizeMake(WIDTH, HEIGHT*3); [self.view addSubview:scrollView]; UISwipeGestureRecognizer *up = \ [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeEvent:)]; up.direction = UISwipeGestureRecognizerDirectionUp; up.delegate = self; [scrollView addGestureRecognizer:up]; UISwipeGestureRecognizer *down = \ [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeEvent:)]; down.direction = UISwipeGestureRecognizerDirectionDown; down.delegate = self; [scrollView addGestureRecognizer:down];}- (void)swipeEvent:(UISwipeGestureRecognizer *)gesture{ NSLog(@"%@", gesture);}- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES;}@end
我直接将手势对象添加进category中,运行时关联上手势对象:
UIScrollView+Swipe.h + UIScrollView+Swipe.m
#importtypedef enum { E_UP = 0x1000, E_DOWN,} EDirection;@protocol UIScrollViewSwipeProtocol - (void)swipeDirection:(EDirection)direction;@end@interface UIScrollView (Swipe)@property (nonatomic, assign) id swipeProtocol;@property (nonatomic, strong, readonly) UISwipeGestureRecognizer *upGesture;@property (nonatomic, strong, readonly) UISwipeGestureRecognizer *downGesture;- (void)activateSwipeGesture;- (void)cancelSwipeGesture;@end
#import "UIScrollView+Swipe.h"#import@interface UIScrollView () @property (nonatomic, strong, readwrite) UISwipeGestureRecognizer *upGesture;@property (nonatomic, strong, readwrite) UISwipeGestureRecognizer *downGesture;@endstatic char swipeProtocolFlag;static char upGestureFlag;static char downGestureFlag;@implementation UIScrollView (Swipe)- (id )swipeProtocol{ return objc_getAssociatedObject(self, &swipeProtocolFlag);}- (void)setSwipeProtocol:(id )swipeProtocol{ objc_setAssociatedObject(self, &swipeProtocolFlag, swipeProtocol, OBJC_ASSOCIATION_ASSIGN);}- (void)setUpGesture:(UISwipeGestureRecognizer *)upGesture{ objc_setAssociatedObject(self, &upGestureFlag, upGesture, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (UISwipeGestureRecognizer *)upGesture{ return objc_getAssociatedObject(self, &upGestureFlag);}- (void)setDownGesture:(UISwipeGestureRecognizer *)downGesture{ objc_setAssociatedObject(self, &downGestureFlag, downGesture, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (UISwipeGestureRecognizer *)downGesture{ return objc_getAssociatedObject(self, &downGestureFlag);}- (void)activateSwipeGesture{ if (self.upGesture == nil) { self.upGesture = \ [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGestureEvents:)]; self.upGesture.direction = UISwipeGestureRecognizerDirectionUp; self.upGesture.delegate = self; [self addGestureRecognizer:self.upGesture]; } if (self.downGesture == nil) { self.downGesture = \ [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGestureEvents:)]; self.downGesture.direction = UISwipeGestureRecognizerDirectionDown; self.downGesture.delegate = self; [self addGestureRecognizer:self.downGesture]; }}- (void)swipeGestureEvents:(UISwipeGestureRecognizer *)gesture{ if (self.swipeProtocol) { if (self.downGesture == gesture) { [self.swipeProtocol swipeDirection:E_DOWN]; } if (self.upGesture == gesture) { [self.swipeProtocol swipeDirection:E_UP]; } }}- (void)cancelSwipeGesture{ [self removeGestureRecognizer:self.upGesture]; [self removeGestureRecognizer:self.downGesture]; self.upGesture = nil; self.downGesture = nil;}- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES;}@end
然后这么使用即可:),so easy!