如何执行 UIAlertAction 的处理程序?
Posted
技术标签:
【中文标题】如何执行 UIAlertAction 的处理程序?【英文标题】:How can I perform the handler of a UIAlertAction? 【发布时间】:2015-04-21 13:42:58 【问题描述】:我正在尝试编写一个帮助程序类以允许我们的应用同时支持UIAlertAction
和UIAlertView
。但是,在为UIAlertViewDelegate
编写alertView:clickedButtonAtIndex:
方法时,我遇到了这个问题:我看不到在UIAlertAction
的处理程序块中执行代码的方法。
我试图通过在一个名为 handlers
的属性中保留一组 UIAlertAction
s 来做到这一点
@property (nonatomic, strong) NSArray *handlers;
然后像这样实现一个委托:
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
UIAlertAction *action = self.handlers[buttonIndex];
if (action.enabled)
action.handler(action);
但是,没有 action.handler
属性,或者确实没有任何我能看到的方法来获取它,因为 UIAlertAction
标头只有:
NS_CLASS_AVAILABLE_ios(8_0) @interface UIAlertAction : NSObject <NSCopying>
+ (instancetype)actionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(UIAlertAction *action))handler;
@property (nonatomic, readonly) NSString *title;
@property (nonatomic, readonly) UIAlertActionStyle style;
@property (nonatomic, getter=isEnabled) BOOL enabled;
@end
还有其他方法可以执行UIAlertAction
的handler
块中的代码吗?
【问题讨论】:
这可能不是您正在寻找的答案(我不确定这是否可能),但是您是否尝试过为您的操作传递一些块而不是使用处理程序?因此,根据所选索引保留要运行的操作的另一个数据源。 @timgcarlson 我是否还需要提供一种方法来传递操作的文本、样式和启用性? 【参考方案1】:经过一些实验,我才明白这一点。原来handler块可以强制转换为函数指针,函数指针可以被执行。
像这样
//Get the UIAlertAction
UIAlertAction *action = self.handlers[buttonIndex];
//Cast the handler block into a form that we can execute
void (^someBlock)(id obj) = [action valueForKey:@"handler"];
//Execute the block
someBlock(action);
【讨论】:
这是使用非公共 API 吗?如果是,Apple 不会让该应用上架。 我不知道苹果会不会为它开发一个应用程序。我将它用于单元测试(不是作为 App 二进制文件的一部分构建的)。 如果您尝试在句柄内外执行相同的代码块,我会将代码重构为单独的方法,或者将代码移动到块中并执行处理程序。在单元测试之外,我想不出为什么需要执行 UIAlertAction 处理程序。 我正在尝试制作一个包装类,以便我可以同时使用 UIAlertController 和 UIAlertView 来保持 iOS 7 的兼容性。【参考方案2】:包装类很棒,嗯?
在.h
:
@interface UIAlertActionWrapper : NSObject
@property (nonatomic, strong) void (^handler)(UIAlertAction *);
@property (nonatomic, strong) NSString *title;
@property (nonatomic, assign) UIAlertActionStyle style;
@property (nonatomic, assign) BOOL enabled;
- (id) initWithTitle: (NSString *)title style: (UIAlertActionStyle)style handler: (void (^)(UIAlertAction *))handler;
- (UIAlertAction *) toAlertAction;
@end
在.m
:
- (UIAlertAction *) toAlertAction
UIAlertAction *action = [UIAlertAction actionWithTitle:self.title style:self.style handler:self.handler];
action.enabled = self.enabled;
return action;
...
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
UIAlertActionWrapper *action = self.helpers[buttonIndex];
if (action.enabled)
action.handler(action.toAlertAction);
您所要做的就是确保将UIAlertActionWrapper
s 插入helpers
而不是UIAlertAction
s。
这样,您可以让所有属性都可以根据自己的喜好获取和设置,并且仍然保留原始类提供的功能。
【讨论】:
请用随附的评论解释任何反对意见,以便我知道将来如何更好地回答:)以上是关于如何执行 UIAlertAction 的处理程序?的主要内容,如果未能解决你的问题,请参考以下文章