Subclassing UIAlertView

前端 未结 3 1516
小鲜肉
小鲜肉 2021-01-16 10:28

Am attempting to subclass UIAlertView to better handle error states in my app. The trouble am having is with the otherButtonTitles nil terminated parameter, when I

相关标签:
3条回答
  • 2021-01-16 10:49

    You can't send a variable set of parameters like that.

    When I subclassed UIAlertView I did this:

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

    Alternatively, you could create a variant of your function that accepts a va_list as a (single) parameter, and then runs the above code.

    Generally, when writing a variadic function, you should include an alternative for handling this eventuality. Apple supply the addButtonWithTitle: method in this case.

    0 讨论(0)
  • 2021-01-16 11:04

    From the UIAlertView Class Reference

    Subclassing Notes

    The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

    There are, however, many other alert view implementations that you may find useful, posted here on CocoaControls.

    0 讨论(0)
  • 2021-01-16 11:07

    Instead of subclassing UIAlertView, I prefer to create simple classes that typically just have a show method that takes a delegate parameter. The delegate protocol then has expressive methods that correspond to the available options.

    While this approach results in more delegate functions than the typical alert view delegate approach, I think it makes the code a lot more readable.

    The code typically looks like this (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)
            }
        }
    }
    

    When you then need to show this alert, just implement the protocol and show the custom alert like this (remember to keep a strong reference to the alert view):

    deleteAlert = DeletePlaceAlertView.showWithDelegate(self)
    
    0 讨论(0)
提交回复
热议问题