【问题标题】:How can I sent an array of strings into an UIActionSheet varargs init method?如何将字符串数组发送到 UIActionSheet varargs init 方法?
【发布时间】:2011-10-15 22:17:00
【问题描述】:

我有一个操作表,其中包含根据情况而有所不同的选项。有足够多的不同按钮标题,我想首先构建这些按钮标题的数组,但我不知道如何将其转换为可变参数格式。

我想做这样的事情:

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 之间进行转换,但我仍然不知道该怎么做。

【问题讨论】:

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


    【解决方案1】:

    你可以试试这个

    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];
    

    【讨论】:

    • 我认为这可行,但我发现它有一些问题,请参阅编辑。
    • 这行得通。不过,似乎没有必要弄乱任何额外的标题。
    【解决方案2】:

    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: 来指定取消按钮的外观。

    【讨论】:

      【解决方案3】:

      为什么不做这样的事情:

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

      【讨论】:

      • 我认为这可行,但我发现它有一些问题,请参阅编辑。
      【解决方案4】:

      这是我尝试过的一种方法,似乎效果很好。如果您想在按钮末尾的“取消”按钮之前添加一个附加按钮,则此方法有效。

      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 上成功测试过了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-21
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        相关资源
        最近更新 更多