Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone UIActionSheet混乱的优雅解决方案_Iphone_Ios_Ipad - Fatal编程技术网

Iphone UIActionSheet混乱的优雅解决方案

Iphone UIActionSheet混乱的优雅解决方案,iphone,ios,ipad,Iphone,Ios,Ipad,我正试图找到一个优雅的解决UIActionSheet问题的方法 我使用的UIActionSheet如下: UIActionSheet * myChoices = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"erase" otherButtonTitles: @"aaa", @"bbb",

我正试图找到一个优雅的解决UIActionSheet问题的方法

我使用的UIActionSheet如下:

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个标题。有什么建议吗?

我更喜欢通过使用一组值来帮助(尽管不是完全解决)这个问题。它使您至少有一个统一的数据源。因此,通过为viewDidLoad或其他内容中的值创建一个数组,在创建操作表时,可以将其更改为:

//where myValuesArray is an array of strings you declared in viewDidLoad
//myValuesArray = [NSArray arrayWithObjects:@"aaa", @"bbb", @"ccc", @"ddd", nil];

UIActionSheet * myChoices = [[UIActionSheet alloc]
    initWithTitle:nil
    delegate:self
    cancelButtonTitle:@"cancel"
    destructiveButtonTitle:@"erase"
    otherButtonTitles:nil];

for(NSString *title in myValuesArray)
{
    [myChoices addButtonWithTitle:@"LMNOP"];
}

然后,在ClickedButtonIndex中,您正在对照完全相同的数组的索引进行检查,我假定这是您的选择。有了它,您还可以在需要更改时更新阵列。我希望这会有所帮助。

因为我创建了一个基于块的
UIAlertView
UIActionSheet
,我个人再也不用基于代理的Apple版本了。
您可以在我的GitHub存储库中下载我的和类

因为它们基于completionBlock模式,所以可读性更强(所有代码都在同一个位置,多个
UIActionSheets
,…)没有公共委托),而且功能更强大(因为块还可以根据需要捕获上下文)


附加说明:如何在NSStrings上
切换/case
请注意,在完成处理程序中的
if/else
测试的otherButtons部分中,您可以使用
开关/case
测试
idx
,或者使用my类别,这将允许您编写与
开关/case
类似的代码,但对于
NSStrings
,因此,您可以在
OHActionSheet
的完成处理程序中使用如下代码:

NSUInteger idx = buttonIndex - sheet.firstOtherButtonIndex;
NSString* buttonName = otherButtons[idx];
[buttonName switchCase:
   @"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 */ },
   ..., nil
];

编辑:现在最新的LLVM编译器支持新的“对象文本”语法,您可以使用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 */
})();

很抱歉为这样一个老问题添加了一个迟来的答案,但谷歌搜索“UIActionSheet blocks”会在这里找到线索,所以我想我会与您分享我编写的这个简单的块实现


干杯

旧问题,但在iOS 8中,新的
UIAlertController
类允许您使用块创建
UIAlertAction
s:

let alertController = UIAlertController(title: "Pancakes", message: "Do you like them with:", preferredStyle: .ActionSheet)

alertController.addAction(UIAlertAction(title: "Maple Syrup", style: .Default, handler: { (alert) -> Void in
    println("Picked syrup")
}))

alertController.addAction(UIAlertAction(title: "Jam", style: .Default, handler: { (alert) -> Void in
    println("Jam? eh?")
}))

alertController.addAction(UIAlertAction(title: "I HATE PANCAKES", style: .Destructive, handler: { (alert) -> Void in
    println("You monster.")
}))

这有助于我始终如一。可能有一个更纯粹的解决方案,但这也是快速和直接的。这也是我通常做的(见我的答案),但使用基于块的动作表更强大(例如,如果我们在同一个ViewController中使用多个
UIActionSheets
,并且允许捕获局部变量,则无需在
UIActionSheet
的标记上切换/case)@rooster请注意,由于Apple自己的
UIActionSheet
中的一些技巧/错误,您的代码有一个问题:当您的初始
otherButtonTitles
参数为
nil
时,无论您之后是否
addButtonWithTitle
,您的工作表的
firstOtherButtonIndex
属性从未设置,并且仍然e> -1(除非他们在最新版本的iOS中修复了此错误,但在4.3中没有修复)。因此,您不能依靠它来计算索引,以从
myValuesArray
数组中获取单击按钮的名称。我在自定义类中遇到了相同的问题,请参阅源代码以了解我是如何修复它的。有趣的是,我从未使用过该属性,因此我还没有遇到过它。@AliSoftware不删除此链接到的repo。L将指向两个repo的自述文件放在屋檐下,以保持URL。@JamesBillingham指出。但我能知道为什么你要我保留它,而不是编辑我的答案,以指向另外两个repo和更新的URL吗?@AliSoftware更新帖子也很好,但维护URL而不是404 URL始终是一个好的做法。只需使用“标记”…就这么简单
let alertController = UIAlertController(title: "Pancakes", message: "Do you like them with:", preferredStyle: .ActionSheet)

alertController.addAction(UIAlertAction(title: "Maple Syrup", style: .Default, handler: { (alert) -> Void in
    println("Picked syrup")
}))

alertController.addAction(UIAlertAction(title: "Jam", style: .Default, handler: { (alert) -> Void in
    println("Jam? eh?")
}))

alertController.addAction(UIAlertAction(title: "I HATE PANCAKES", style: .Destructive, handler: { (alert) -> Void in
    println("You monster.")
}))