如何将字符串数组发送到UIActionSheet varargs init方法?

时间:2011-10-15 22:17:01

标签: iphone objective-c ios uiactionsheet variadic-functions

我有一个行动表,其中的选项会根据具体情况而有所不同。有足够的不同按钮标题,我想首先构建这些按钮标题的数组,但我无法弄清楚如何将其转换为varargs格式。

我想做这样的事情:

NSMutableArray *buttonTitles = [NSMutableArray array];
if (condition1) {
    [buttonTitles addObject: @"Do action 1"];
}
if (condition2) {
    [buttonTitles addObject: @"Do action 2"];
}
if (condition3) {
    [buttonTitles addObject: @"Do action 3"];
}
if (condition4) {
    [buttonTitles addObject: @"Do action 4"];
}
UIActionSheet *actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: @"Cancel" destructiveButtonTitle: nil otherButtonTitles: buttonTitles] autorelease];

现在很明显,如果我必须这样做,我可以这样做:

UIActionSheet *actionSheet = nil;
if (condition1 && condition2 && condition3 && condition4) {
    actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: @"Cancel" destructiveButtonTitle: nil otherButtonTitles: @"Do action1", @"Do action2", @"Do action3", @"Do action 4", nil] autorelease];    
} else if (condition1 && condition2 && condition3 && !condition4) {
    actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: @"Cancel" destructiveButtonTitle: nil otherButtonTitles: @"Do action1", @"Do action2", @"Do action3", nil] autorelease];    
} 
// else ...
// about 14 other cases!

但那太可怕了。有人知道一些很好的语法糖来帮助我吗?

修改: 有人建议我使用addButtonWithTitle,面对它看起来很棒,不幸的是,这会在取消按钮之后放置额外的按钮,这是不可取的。

我认为这是Apple代码的错误,因为他们在addButtonWithTitle上的文档指出:

// adds a button with the title. returns the index (0 based) of where it was added. buttons are displayed in the order added except for the
// destructive and cancel button which will be positioned based on HI requirements. buttons cannot be customized.

HI要求(Apple自己的人机界面指南)赞成取消按钮低于所有其他选项,所以我说Apple搞砸了。当然,这对我没有帮助,所以我回过头来尝试在NSArray和varargs之间进行转换,我仍然不知道该怎么做。

4 个答案:

答案 0 :(得分:18)

你可以试试这个

NSMutableArray *buttonTitles = [NSMutableArray array];
if (condition1) {
    [buttonTitles addObject: @"Do action 1"];
}
if (condition2) {
    [buttonTitles addObject: @"Do action 2"];
}
if (condition3) {
    [buttonTitles addObject: @"Do action 3"];
}
if (condition4) {
    [buttonTitles addObject: @"Do action 4"];
}
[buttonTitles addObject: @"Cancel"];
UIActionSheet *actionSheet = [[[UIActionSheet alloc] initWithTitle: nil delegate: self cancelButtonTitle: nil destructiveButtonTitle: nil otherButtonTitles: nil] autorelease];

for (NSString *title in buttonTitles) {
    [actionSheet addButtonWithTitle: title];
}

[actionSheet setCancelButtonIndex: [buttonTitles count] - 1];

答案 1 :(得分:5)

Himanshu回答的一个变种:

    UIActionSheet * as = [[UIActionSheet alloc] initWithTitle:@"Share" 
                                                 delegate:self 
                                        cancelButtonTitle:nil /* don't set Cancel title here! */
                                   destructiveButtonTitle:nil 
                                        otherButtonTitles:nil];
int cancelButtonIndex = 0; // will remain 0 if no other buttons besides "Cancel"
if ( canShareBySMS )
{
    [as addButtonWithTitle:kSMSButtonText];
    cancelButtonIndex++;
}
if ( canShareByMail )
{
    [as addButtonWithTitle:kEmailButtonText];
    cancelButtonIndex++;
}
/* etc. */

// after all other buttons have been added, include Cancel
[as addButtonWithTitle:@"Cancel"];
[as setCancelButtonIndex:cancelButtonIndex];

[as showInView:self.sharingViewController.view];
[as release];

注意:您的UIActionSheetDelegate方法应检查按钮标题而不是buttonIndex:

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex {
    if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:kSMSButtonText]) {
    //share via sms
    }else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:kEmailButtonText]) {
    //share via mail
    }
}

我认为人们错过的关键细节是在initWithTitle选择器中设置cancelButton,而不是在所有其他按钮之后添加它并通过调用setCancelButtonIndex指定取消按钮的外观:。

答案 2 :(得分:4)

为什么不做这样的事情:

for (Nstring *button in buttonTitles)
  [actionSheet addButtonWithTitle:button];

答案 3 :(得分:0)

这是我试过的方法似乎工作得很好。如果要在“取消”按钮之前在按钮末尾添加其他按钮,则此方法有效。

NSString * optionalButton = nil;
if (condition4) {
  optionalButton = @"Some Additional Option";
}

UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:@"Some Title" 
                                                          delegate:self 
                                                 cancelButtonTitle:@"Cancel" 
                                            destructiveButtonTitle:nil 
                                                 otherButtonTitles:@"Button 1",@"Button 2",@"Button 3",optionalButton, nil];


[actionSheet showInView:self.view];

如果你的条件(条件4)不满足,可以在按钮列表的末尾添加额外的'nil'。

我已经在iOS7上成功测试了这个。