UIActionsheet的block实现

来源:互联网 发布:c语言有多少函数 编辑:程序博客网 时间:2024/05/18 00:14

IOS UIKIT framework的UIActionsheet是不支持block方式的,为什么我们需要block支持呢?


原因有

1. block的代码更灵活,而同一个NSObject派生对象里,通常只出现一个UIActionsheet delegate实现,出现多个情况变得复杂,需要if else判断,并且需要property 来保存 UIActionsheet以便在delegate回调中加以判断。

2.更麻烦的情况是,在有参数需要传递到delegate回调中时,更麻烦,代码将更乱。 


解决方法,便是引入block

client调用的例子


[sheet showInView:view          handler:^(UIActionSheet *actionSheet, NSInteger buttonIndex) {              if (buttonIndex == [actionSheet cancelButtonIndex]) {                  NSLog(@"Cancel button index tapped");              } else if (buttonIndex == [actionSheet destructiveButtonIndex]) {                  NSLog(@"Destructive button index tapped");              } else  {                  NSLog(@"Button %i tapped", buttonIndex);              }                                }];

源代码如下


#import "UIActionSheet+Blocks.h"
#import <objc/runtime.h>
/*
* Runtime association key.
*/
static NSString *kHandlerAssociatedKey = @"kHandlerAssociatedKey";
@implementation UIActionSheet (Blocks)
#pragma mark - Showing
/*
* Shows the sheet from a view.
*/
- (void)showInView:(UIView *)view handler:(UIActionSheetHandler)handler {
    
    objc_setAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey), handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setDelegate:self];
    [self showInView:view];
}
/*
* Shows the sheet from a bar button item.
*/
- (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated handler:(UIActionSheetHandler)handler {
    
    objc_setAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey), handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setDelegate:self];
    [self showFromBarButtonItem:item animated:animated];
}
/*
* Shows the sheet from a rect.
*/
- (void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated handler:(UIActionSheetHandler)handler {
    
    objc_setAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey), handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setDelegate:self];
    [self showFromRect:rect inView:view animated:animated];
}
/*
* Shows the sheet from a tab bar.
*/
- (void)showFromTabBar:(UITabBar *)view handler:(UIActionSheetHandler)handler {
    
    objc_setAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey), handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setDelegate:self];
    [self showFromTabBar:view];
}
/*
* Shows the sheet from a toobar.
*/
- (void)showFromToolbar:(UIToolbar *)view handler:(UIActionSheetHandler)handler {
    
    objc_setAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey), handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setDelegate:self];
    [self showFromToolbar:view];
}
#pragma mark - UIActionSheetDelegate
/*
* Sent to the delegate when the user clicks a button on an action sheet.
*/
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    
    UIActionSheetHandler completionHandler = objc_getAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey));
    
    if (completionHandler != nil) {
        
        completionHandler(actionSheet, buttonIndex);
    }
}
@end


实现分析


/*
* Shows the sheet from a bar button item.
*/
- (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated handler:(UIActionSheetHandler)handler {
    
    objc_setAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey), handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setDelegate:self];
    [self showFromBarButtonItem:item animated:animated];
}

1.代码以category方式实现,更加方便的引入到我们的工程中,成本低,不引入新的class

2.通过objc_setAssociatedObject runtime函数,像class中加入handler property,以便在delegate里加调该block


#pragma mark - UIActionSheetDelegate
/*
* Sent to the delegate when the user clicks a button on an action sheet.
*/
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    
    UIActionSheetHandler completionHandler = objc_getAssociatedObject(self, (__bridge const void *)(kHandlerAssociatedKey));
    
    if (completionHandler != nil) {
        
        completionHandler(actionSheet, buttonIndex);
    }
}

3.在category中实现了delegate回调方法,并调用了该block handler.


https://github.com/emenegro/action-sheet-blocks




原创粉丝点击