2014-09-29 33 views
3

我试图通过文本编辑,Ok和取消按钮来设置一个非常简单的UIAlertView,并且我想根据文本编辑的内容禁用Ok按钮。UIAlertView的正向可变参数

为了能够保留委托,以便他不会在警报视图之前消失(并且因此一旦用户对警报视图执行某些操作就会导致崩溃),我已将其分类。现在,我希望能够从我的init方法转发otherButtonTitles参数来UIAlertView init方法,但由于某些原因,只是这样做:

- (id)initWithTitle:(NSString *)title 
      message:(NSString*)message 
      delegate:(id /*<UIAlertViewDelegate>*/)delegate 
    cancelButtonTitle:(NSString *)cancelButtonTitle 
    otherButtonTitles:(NSString *)otherButtonTitles, ... { 

    if (self = [super initWithTitle:title 
          message:message 
          delegate:delegate 
        cancelButtonTitle:cancelButtonTitle 
        otherButtonTitles:otherButtonTitles, nil]) { 
     //stuff 
    } 

只增加了args来第一个元素警报查看。我发现,其实我可以手动将按钮添加到使用此警报视图:

va_list args; 
va_start(args, otherButtonTitles); 
for (NSString *buttonTitle = otherButtonTitles; buttonTitle != nil; buttonTitle = va_arg(args, NSString*)) { 
    [self addButtonWithTitle:buttonTitle]; 
} 
va_end(args); 

但后来,我alertViewShouldEnableFirstOtherButton委托方法不再被调用,with the probable explanation in this post

因此,如何正确转发我的otherButtonTitlesUIAlertView init方法?

+0

我总是被这样的事实困扰,在C你可以收集与va_list的可变参数,但没有办法,进一步传递到另一个可变参数函数。我们知道阿比和边界,但不是先生。 – user3125367 2014-09-29 15:27:18

+0

顺便说一句,如果您熟悉objc运行时(objc_msgSend),并确保其他按钮的数量永远不会超过某个固定的限制,那么您可以使用这里描述的hack:http://c-faq.com/varargs/handoff.html – user3125367 2014-09-29 15:37:25

+0

@ user3125367感谢您的链接,但这是完全不可行的,因为我受到'UIAlertView' init方法的签名的约束,该方法不需要va_list但是可变参数... – JBL 2014-09-29 15:40:04

回答

0

让我们减少击键然后:

NSMutableArray *otherButtonTitles = [NSMutableArray array]; 
// .. collect varargs into ^^^ 

#define T(n) ([otherButtonTitles objectAtIndex:n]) 
#define CASE(n, ...) case n: self = [super initWithTitle:title \ 
               message:message \ 
               delegate:delegate \ 
             cancelButtonTitle:cancelButtonTitle \ 
             otherButtonTitles:__VA_ARGS__, nil]; \ 
          break 

switch ([otherButtonTitles count]) { 
    CASE(0, nil); 
    CASE(1, T(0)); 
    CASE(2, T(0), T(1)); 
    CASE(3, T(0), T(1), T(2)); 
    // ... repeat until bored ... 
    default: @throw @"too many buttons"; // or return nil 
}