UIScrollView中的手势

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 ()<UIScrollViewDelegate>

@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 ()<UIGestureRecognizerDelegate>

@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

#import <UIKit/UIKit.h>

typedef enum {

    E_UP    = 0x1000,
    E_DOWN,

} EDirection;

@protocol UIScrollViewSwipeProtocol <NSObject>

- (void)swipeDirection:(EDirection)direction;

@end

@interface UIScrollView (Swipe)

@property (nonatomic, assign)      id<UIScrollViewSwipeProtocol>  swipeProtocol;
@property (nonatomic, strong, readonly) UISwipeGestureRecognizer *upGesture;
@property (nonatomic, strong, readonly) UISwipeGestureRecognizer *downGesture;

- (void)activateSwipeGesture;
- (void)cancelSwipeGesture;

@end
#import "UIScrollView+Swipe.h"
#import <objc/runtime.h>

@interface UIScrollView ()<UIGestureRecognizerDelegate>

@property (nonatomic, strong, readwrite) UISwipeGestureRecognizer *upGesture;
@property (nonatomic, strong, readwrite) UISwipeGestureRecognizer *downGesture;

@end

static char swipeProtocolFlag;
static char upGestureFlag;
static char downGestureFlag;


@implementation UIScrollView (Swipe)

- (id<UIScrollViewSwipeProtocol>)swipeProtocol
{
    return objc_getAssociatedObject(self, &swipeProtocolFlag);
}

- (void)setSwipeProtocol:(id<UIScrollViewSwipeProtocol>)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!

原文地址:https://www.cnblogs.com/YouXianMing/p/3718447.html