UIActionSheet+BlocksKit.m 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //
  2. // UIActionSheet+BlocksKit.m
  3. // BlocksKit
  4. //
  5. #import "NSObject+A2BlockDelegate.h"
  6. #import "NSObject+A2DynamicDelegate.h"
  7. #import "UIActionSheet+BlocksKit.h"
  8. #pragma mark Custom delegate
  9. @interface A2DynamicUIActionSheetDelegate : A2DynamicDelegate <UIActionSheetDelegate>
  10. @end
  11. @implementation A2DynamicUIActionSheetDelegate
  12. - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
  13. {
  14. id realDelegate = self.realDelegate;
  15. if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)])
  16. [realDelegate actionSheet:actionSheet clickedButtonAtIndex:buttonIndex];
  17. void (^block)(void) = self.handlers[@(buttonIndex)];
  18. if (block) block();
  19. }
  20. - (void)willPresentActionSheet:(UIActionSheet *)actionSheet
  21. {
  22. id realDelegate = self.realDelegate;
  23. if (realDelegate && [realDelegate respondsToSelector:@selector(willPresentActionSheet:)])
  24. [realDelegate willPresentActionSheet:actionSheet];
  25. void (^block)(UIActionSheet *) = [self blockImplementationForMethod:_cmd];
  26. if (block) block(actionSheet);
  27. }
  28. - (void)didPresentActionSheet:(UIActionSheet *)actionSheet
  29. {
  30. id realDelegate = self.realDelegate;
  31. if (realDelegate && [realDelegate respondsToSelector:@selector(didPresentActionSheet:)])
  32. [realDelegate didPresentActionSheet:actionSheet];
  33. void (^block)(UIActionSheet *) = [self blockImplementationForMethod:_cmd];
  34. if (block) block(actionSheet);
  35. }
  36. - (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex
  37. {
  38. id realDelegate = self.realDelegate;
  39. if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)])
  40. [realDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex];
  41. void (^block)(UIActionSheet *, NSInteger) = [self blockImplementationForMethod:_cmd];
  42. if (block) block(actionSheet, buttonIndex);
  43. }
  44. - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
  45. {
  46. id realDelegate = self.realDelegate;
  47. if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)])
  48. [realDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex];
  49. void (^block)(UIActionSheet *, NSInteger) = [self blockImplementationForMethod:_cmd];
  50. if (block) block(actionSheet, buttonIndex);
  51. }
  52. - (void)actionSheetCancel:(UIActionSheet *)actionSheet
  53. {
  54. id realDelegate = self.realDelegate;
  55. if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheetCancel:)])
  56. [realDelegate actionSheetCancel:actionSheet];
  57. void (^block)(void) = actionSheet.bk_cancelBlock;
  58. if (block) block();
  59. }
  60. @end
  61. #pragma mark - Category
  62. @implementation UIActionSheet (BlocksKit)
  63. @dynamic bk_willShowBlock, bk_didShowBlock, bk_willDismissBlock, bk_didDismissBlock;
  64. + (void)load
  65. {
  66. @autoreleasepool {
  67. [self bk_registerDynamicDelegate];
  68. [self bk_linkDelegateMethods:@{
  69. @"bk_willShowBlock": @"willPresentActionSheet:",
  70. @"bk_didShowBlock": @"didPresentActionSheet:",
  71. @"bk_willDismissBlock": @"actionSheet:willDismissWithButtonIndex:",
  72. @"bk_didDismissBlock": @"actionSheet:didDismissWithButtonIndex:"
  73. }];
  74. }
  75. }
  76. #pragma mark Initializers
  77. + (id)bk_actionSheetWithTitle:(NSString *)title {
  78. return [[[self class] alloc] bk_initWithTitle:title];
  79. }
  80. - (id)bk_initWithTitle:(NSString *)title {
  81. self = [self initWithTitle:title delegate:self.bk_dynamicDelegate cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
  82. if (!self) { return nil; }
  83. self.delegate = self.bk_dynamicDelegate;
  84. return self;
  85. }
  86. #pragma mark Actions
  87. - (NSInteger)bk_addButtonWithTitle:(NSString *)title handler:(void (^)(void))block {
  88. NSAssert(title.length, @"A button without a title cannot be added to an action sheet.");
  89. NSInteger index = [self addButtonWithTitle:title];
  90. [self bk_setHandler:block forButtonAtIndex:index];
  91. return index;
  92. }
  93. - (NSInteger)bk_setDestructiveButtonWithTitle:(NSString *)title handler:(void (^)(void))block {
  94. NSInteger index = [self bk_addButtonWithTitle:title handler:block];
  95. self.destructiveButtonIndex = index;
  96. return index;
  97. }
  98. - (NSInteger)bk_setCancelButtonWithTitle:(NSString *)title handler:(void (^)(void))block {
  99. NSInteger cancelButtonIndex = self.cancelButtonIndex;
  100. if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && !title.length)
  101. title = NSLocalizedString(@"Cancel", nil);
  102. if (title.length)
  103. cancelButtonIndex = [self addButtonWithTitle:title];
  104. [self bk_setHandler:block forButtonAtIndex:cancelButtonIndex];
  105. self.cancelButtonIndex = cancelButtonIndex;
  106. return cancelButtonIndex;
  107. }
  108. #pragma mark Properties
  109. - (void)bk_setHandler:(void (^)(void))block forButtonAtIndex:(NSInteger)index {
  110. A2DynamicUIActionSheetDelegate *delegate = self.bk_ensuredDynamicDelegate;
  111. if (block) {
  112. delegate.handlers[@(index)] = [block copy];
  113. } else {
  114. [delegate.handlers removeObjectForKey:@(index)];
  115. }
  116. }
  117. - (void (^)(void))bk_handlerForButtonAtIndex:(NSInteger)index
  118. {
  119. return [self.bk_dynamicDelegate handlers][@(index)];
  120. }
  121. - (void (^)(void))bk_cancelBlock
  122. {
  123. return [self bk_handlerForButtonAtIndex:self.cancelButtonIndex];
  124. }
  125. - (void)bk_setCancelBlock:(void (^)(void))block
  126. {
  127. [self bk_setHandler:block forButtonAtIndex:self.cancelButtonIndex];
  128. }
  129. @end