UIGestureRecognizer+BlocksKit.m 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // UIGestureRecognizer+BlocksKit.m
  3. // BlocksKit
  4. //
  5. #import <objc/runtime.h>
  6. #import "UIGestureRecognizer+BlocksKit.h"
  7. static const void *BKGestureRecognizerBlockKey = &BKGestureRecognizerBlockKey;
  8. static const void *BKGestureRecognizerDelayKey = &BKGestureRecognizerDelayKey;
  9. static const void *BKGestureRecognizerShouldHandleActionKey = &BKGestureRecognizerShouldHandleActionKey;
  10. @interface UIGestureRecognizer (BlocksKitInternal)
  11. @property (nonatomic, setter = bk_setShouldHandleAction:) BOOL bk_shouldHandleAction;
  12. - (void)bk_handleAction:(UIGestureRecognizer *)recognizer;
  13. @end
  14. @implementation UIGestureRecognizer (BlocksKit)
  15. + (id)bk_recognizerWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block delay:(NSTimeInterval)delay
  16. {
  17. return [[[self class] alloc] bk_initWithHandler:block delay:delay];
  18. }
  19. - (id)bk_initWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block delay:(NSTimeInterval)delay
  20. {
  21. self = [self initWithTarget:self action:@selector(bk_handleAction:)];
  22. if (!self) return nil;
  23. self.bk_handler = block;
  24. self.bk_handlerDelay = delay;
  25. return self;
  26. }
  27. + (id)bk_recognizerWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block
  28. {
  29. return [self bk_recognizerWithHandler:block delay:0.0];
  30. }
  31. - (id)bk_initWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block
  32. {
  33. return (self = [self bk_initWithHandler:block delay:0.0]);
  34. }
  35. - (void)bk_handleAction:(UIGestureRecognizer *)recognizer
  36. {
  37. void (^handler)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) = recognizer.bk_handler;
  38. if (!handler) return;
  39. NSTimeInterval delay = self.bk_handlerDelay;
  40. CGPoint location = [self locationInView:self.view];
  41. void (^block)(void) = ^{
  42. if (!self.bk_shouldHandleAction) return;
  43. handler(self, self.state, location);
  44. };
  45. self.bk_shouldHandleAction = YES;
  46. if (!delay) {
  47. block();
  48. return;
  49. }
  50. dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
  51. dispatch_after(popTime, dispatch_get_main_queue(), block);
  52. }
  53. - (void)bk_setHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))handler
  54. {
  55. objc_setAssociatedObject(self, BKGestureRecognizerBlockKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC);
  56. }
  57. - (void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))bk_handler
  58. {
  59. return objc_getAssociatedObject(self, BKGestureRecognizerBlockKey);
  60. }
  61. - (void)bk_setHandlerDelay:(NSTimeInterval)delay
  62. {
  63. NSNumber *delayValue = delay ? @(delay) : nil;
  64. objc_setAssociatedObject(self, BKGestureRecognizerDelayKey, delayValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  65. }
  66. - (NSTimeInterval)bk_handlerDelay
  67. {
  68. return [objc_getAssociatedObject(self, BKGestureRecognizerDelayKey) doubleValue];
  69. }
  70. - (void)bk_setShouldHandleAction:(BOOL)flag
  71. {
  72. objc_setAssociatedObject(self, BKGestureRecognizerShouldHandleActionKey, @(flag), OBJC_ASSOCIATION_COPY_NONATOMIC);
  73. }
  74. - (BOOL)bk_shouldHandleAction
  75. {
  76. return [objc_getAssociatedObject(self, BKGestureRecognizerShouldHandleActionKey) boolValue];
  77. }
  78. - (void)bk_cancel
  79. {
  80. self.bk_shouldHandleAction = NO;
  81. }
  82. @end