我试图找到一个优雅的UIActionSheet问题的解决方案.
我像这样使用UIActionSheets:
UIActionSheet * myChoices = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"erase" otherButtonTitles: @"aaa",@"bbb",@"ccc",@"ddd",nil];
问题是,为了发现用户选择的选项,我必须使用:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { switch ([actionSheet tag]) { case 0: ... case 1: ... case 2: ... case 3: ... } }
基于索引的这种情况很糟糕,因为如果我改变了aaa,bbb,ccc等的顺序,我必须在动作表上更改大小写顺序.这个索引的东西并不是一个可靠的解决方案.
我试图想象一种方法来做到这一点,并成为独立于索引但没有得到任何满意的解决方案.使用buttonTitleAtIndex也不够好,因为我的应用程序是本地化的,我必须为每个条目测试n个标题.有什么建议?
解决方法
由于我创建了基于块的UIAlertView和UIActionSheet版本,我个人再也不会使用基于委托的Apple版本.
您可以在我的GitHub存储库中下载我的
您可以在我的GitHub存储库中下载我的
OHActionSheet
和
OHAlertView
类.
因为它们基于completionBlock模式,所以它们更具可读性(所有代码都在同一个地方,没有多个UIActionSheets的公共委托,……),并且功能更强大(因为块也可以根据需要捕获它们的上下文).
NSArray* otherButtons = @[ @"aaa",@"ddd" ]; [OHActionSheet showSheetInView:self.view title:nil cancelButtonTitle:@"cancel" destructiveButtonTitle:@"erase" otherButtonTitles:otherButtons completion:^(OHActionSheet* sheet,NSInteger buttonIndex) { if (buttonIndex == sheet.cancelButtonIndex) { // cancel } else if (buttonIndex == sheet.destructiveButtonIndex) { // erase } else { NSUInteger idx = buttonIndex - sheet.firstOtherButtonIndex; // Some magic here: thanks to the blocks capturing capability,// the "otherButtons" array is accessible in the completion block! Nsstring* buttonName = otherButtons[idx]; // Do whatever you want with idx and buttonName } }];
附加说明:如何在Nsstrings上切换/大小写
请注意,在完成处理程序中if / else测试的otherButtons部分,您可以使用开关/ case测试idx,或使用我的ObjcSwitch
类别,这将允许您编写类似开关/类似代码但是对于Nsstrings,所以你可以在你的OHActionSheet的完成处理程序中有这样的代码:
NSUInteger idx = buttonIndex - sheet.firstOtherButtonIndex; Nsstring* buttonName = otherButtons[idx]; [buttonName switchCase: @"aaa",^{ /* Some code here to execute for the "aaa" button */ },^{ /* Some code here to execute for the "bbb" button */ },^{ /* Some code here to execute for the "ccc" button */ },...,nil ];
编辑:既然最新的LLVM编译器支持新的“Object Literals”语法,您可以使用NSDictionary的紧凑语法执行与ObjcSwitch相同的操作:
((dispatch_block_t)@{ @"aaa": ^{ /* Some code here to execute for the "aaa" button */ },@"bbb": ^{ /* Some code here to execute for the "bbb" button */ },@"ccc": ^{ /* Some code here to execute for the "ccc" button */ },}[buttonName] ?:^{ /* Some code here to execute for defaults if no case found above */ })();