UIGestureRecognizer+BlocksKit.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //
  2. // UIGestureRecognizer+BlocksKit.h
  3. // BlocksKit
  4. //
  5. #import <UIKit/UIKit.h>
  6. /** Block functionality for UIGestureRecognizer.
  7. Use of the delay property is pretty straightforward, although
  8. cancellation might be a little harder to swallow. An example
  9. follows:
  10. UITapGestureRecognizer *singleTap = [UITapGestureRecognizer recognizerWithHandler:^(id sender) {
  11. NSLog(@"Single tap.");
  12. } delay:0.18];
  13. [self addGestureRecognizer:singleTap];
  14. UITapGestureRecognizer *doubleTap = [UITapGestureRecognizer recognizerWithHandler:^(id sender) {
  15. [singleTap cancel];
  16. NSLog(@"Double tap.");
  17. }];
  18. doubleTap.numberOfTapsRequired = 2;
  19. [self addGestureRecognizer:doubleTap];
  20. Believe it or not, the above code is fully memory-safe and efficient. Eagle-eyed coders
  21. will notice that this setup emulates UIGestureRecognizer's requireGestureRecognizerToFail:,
  22. and, yes, it totally apes it. Not only is this setup much faster on the user's end of
  23. things, it is more flexible and allows for much more complicated setups.
  24. Includes code by the following:
  25. - [Kevin O'Neill](https://github.com/kevinoneill)
  26. - [Zach Waldowski](https://github.com/zwaldowski)
  27. @warning UIGestureRecognizer is only available on a platform with UIKit.
  28. @warning It is not recommended to use the Apple-supplied locationInView and state
  29. methods on a *delayed* block-backed gesture recognizer, as these properties are
  30. likely to have been cleared by the time by the block fires. It is instead recommended
  31. to use the arguments provided to the block.
  32. */
  33. @interface UIGestureRecognizer (BlocksKit)
  34. /** An autoreleased gesture recognizer that will, on firing, call
  35. the given block asynchronously after a number of seconds.
  36. @return An autoreleased instance of a concrete UIGestureRecognizer subclass, or `nil`.
  37. @param block The block which handles an executed gesture.
  38. @param delay A number of seconds after which the block will fire.
  39. */
  40. + (id)bk_recognizerWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block delay:(NSTimeInterval)delay;
  41. /** Initializes an allocated gesture recognizer that will call the given block
  42. after a given delay.
  43. An alternative to the designated initializer.
  44. @return An initialized instance of a concrete UIGestureRecognizer subclass or `nil`.
  45. @param block The block which handles an executed gesture.
  46. @param delay A number of seconds after which the block will fire.
  47. */
  48. - (id)bk_initWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block delay:(NSTimeInterval)delay NS_REPLACES_RECEIVER;
  49. /** An autoreleased gesture recognizer that will call the given block.
  50. For convenience and compatibility reasons, this method is indentical
  51. to using recognizerWithHandler:delay: with a delay of 0.0.
  52. @return An initialized and autoreleased instance of a concrete UIGestureRecognizer
  53. subclass, or `nil`.
  54. @param block The block which handles an executed gesture.
  55. */
  56. + (id)bk_recognizerWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block;
  57. /** Initializes an allocated gesture recognizer that will call the given block.
  58. This method is indentical to calling initWithHandler:delay: with a delay of 0.0.
  59. @return An initialized instance of a concrete UIGestureRecognizer subclass or `nil`.
  60. @param block The block which handles an executed gesture.
  61. */
  62. - (id)bk_initWithHandler:(void (^)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location))block NS_REPLACES_RECEIVER;
  63. /** Allows the block that will be fired by the gesture recognizer
  64. to be modified after the fact.
  65. */
  66. @property (nonatomic, copy, setter = bk_setHandler:) void (^bk_handler)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location);
  67. /** Allows the length of the delay after which the gesture
  68. recognizer will be fired to modify. */
  69. @property (nonatomic, setter = bk_setHandlerDelay:) NSTimeInterval bk_handlerDelay;
  70. /** If the recognizer happens to be fired, calling this method
  71. will stop it from firing, but only if a delay is set.
  72. @warning This method is not for arbitrarily canceling the
  73. firing of a recognizer, but will only function for a block
  74. handler *after the recognizer has already been fired*. Be
  75. sure to make your delay times accomodate this likelihood.
  76. */
  77. - (void)bk_cancel;
  78. @end