对UIAlertView进行子类化

时间:2011-11-29 11:20:10

标签: objective-c ios uialertview null subclassing

我试图将UIAlertView子类化以更好地处理我的应用中的错误状态。我遇到的麻烦是使用 otherButtonTitles nil终止参数,当我创建我的子类时,它只是拾取列表中的第一个字符串而不是所有字符串

+ (ErrorAlertView *)displayErrorAlertViewWithTitle:(NSString *)title 
                                           message:(NSString *)message 
                                          delegate:(id<UIAlertViewDelegate>)delegate 
                                     errorDelegate:(id<ErrorAlertViewDelegate>)errorDelegate
                                 cancelButtonTitle:(NSString *)cancelButtonTitle 
                                        displayNow:(BOOL)displayNow
                                               tag:(NSUInteger)tag
                                 otherButtonTitles:(NSString *)otherButtonTitles, ...;

{

  ErrorAlertView *errorAlertView = [[ErrorAlertView alloc]  initWithTitle:title 
                                                                  message:message 
                                                                 delegate:delegate 
                                                        cancelButtonTitle:cancelButtonTitle 
                                                        otherButtonTitles:otherButtonTitles, nil];


  errorAlertView.errorDelegate = errorDelegate;
  errorAlertView.tag = tag;

  if (displayNow) {

    [errorAlertView show];

  }

  return [errorAlertView autorelease];


}

如果我进行以下调用上述方法:

[ErrorAlertView displayErrorAlertViewWithTitle:[self noInternetConnectionAlertViewTitle] 
                                           message:[self noInternetConnectionAlertViewMessage] 
                                          delegate:self 
                                     errorDelegate:errorDelegate 
                                 cancelButtonTitle:@"OK" 
                                        displayNow:YES 
                                               tag:ErrorAlertTagInternetConnectionError 
                                 @"Try again",@"Setting", nil];

显示UIAlertView时只显示@“再试一次”按钮。

3 个答案:

答案 0 :(得分:14)

来自UIAlertView Class Reference

  

子类注释

     

UIAlertView类旨在按原样使用,但不是   支持子类化。此类的视图层次结构是私有的   不得修改。

但是,有许多其他警报视图实现,您可能会觉得有用,已发布here on CocoaControls

答案 1 :(得分:5)

您无法发送一组可变参数。

当我将UIAlertView子类化时,我做到了这一点:

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

或者,您可以创建函数的变体,将va_list作为(单个)参数接受,然后运行上面的代码。

通常,在编写可变参数函数时,应该包含一个替代方法来处理这种可能性。 Apple在这种情况下提供了addButtonWithTitle:方法。

答案 2 :(得分:1)

我更喜欢创建简单的类,而不是子类化UIAlertView,它通常只有一个show方法,它接受一个委托参数。然后,委托协议具有与可用选项相对应的表达方法。

虽然这种方法比典型的警报视图委托方法产生更多的委托功能,但我认为它使代码更具可读性。

代码通常看起来像这样(Swift):

@objc protocol DeleteUniverseAlertViewDelegate {
    func deleteUniverseAlertViewDidConfirmDelete(view: DeleteUniverseAlertView)
}


class DeleteUniverseAlertView : NSObject, UIAlertViewDelegate {

    private weak var delegate: DeleteUniverseAlertViewDelegate? = nil

    class func showWithDelegate(delegate: DeleteUniverseAlertViewDelegate) -> DeleteUniverseAlertView {
        let view = DeleteUniverseAlertView()
        view.delegate = delegate
        UIAlertView(title: "Delete universe?", message: "Are you really, really sure about this?", delegate: view, cancelButtonTitle: "Cancel", otherButtonTitles: "Yes, delete!").show()
        return view
    }

    func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
        if (buttonIndex > 0) {
            delegate?.deleteUniverseAlertViewDidConfirmDelete(self)
        }
    }
}

当您需要显示此警报时,只需实施协议并显示此类自定义警报(请记住保留对警报视图的强引用):

deleteAlert = DeletePlaceAlertView.showWithDelegate(self)