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
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.
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.
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)