Подкласс UIAlertView
Я пытаюсь создать подкласс UIAlertView для лучшей обработки состояний ошибок в моем приложении. Проблема в том, что с параметром otherButtonTitles nil terminated, когда я создаю свой подкласс, он выбирает только первую строку в списке, а не все строки
+ (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 ответа
Вы не можете отправить переменную набор параметров, как это.
Когда я создал подкласс 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: в этом случае.
Из ссылки на класс UIAlertView
Примечания по подклассам
Класс UIAlertView предназначен для использования как есть и не поддерживает создание подклассов. Иерархия представления для этого класса является закрытой и не должна быть изменена.
Однако есть много других реализаций представления предупреждений, которые могут оказаться полезными, размещенные здесь на CocoaControls.
Вместо того, чтобы создавать подклассы 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)