Как написать обработчики событий для кнопок в UIAlertView?
Скажем, у меня есть предупреждение, подобное следующим в obj c
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:@"download"];
[alert show];
[alert release];
Теперь у нас есть две кнопки в представлении оповещения (Ok и Download), как написать обработчик событий для загрузки?
Ответы
Ответ 1
Сначала вам нужно добавить UIAlertViewDelegate в заголовочный файл, как показано ниже:
Заголовочный файл (.h)
@interface YourViewController : UIViewController<UIAlertViewDelegate>
Файл реализации (.m)
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:@"download"];
[alert show];
[alert release];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
//Code for OK button
}
if (buttonIndex == 1)
{
//Code for download button
}
}
Ответ 2
Теперь, когда большинство устройств iOS имеют версии firmare с блоками, поддерживают его анахронизм, чтобы использовать неуклюжий API обратного вызова для обработки нажатия кнопок. Блоки - это путь, см., Например, классы Lambda Alert на GitHub:
CCAlertView *alert = [[CCAlertView alloc]
initWithTitle:@"Test Alert"
message:@"See if the thing works."];
[alert addButtonWithTitle:@"Foo" block:^{ NSLog(@"Foo"); }];
[alert addButtonWithTitle:@"Bar" block:^{ NSLog(@"Bar"); }];
[alert addButtonWithTitle:@"Cancel" block:NULL];
[alert show];
Ответ 3
Объявите свои UIAlertViews как известные.
UIAlertView *alertLogout=[[UIAlertView alloc]initWithTitle:@"Title" message:@"Stop Application?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil];
[alertLogout show];
[alertLogout release];
установите делегат для себя и реализуйте этот метод.
-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(actionSheet== alertLogout) {//alertLogout
if (buttonIndex == 0){
}else if(buttonIndex==1){
}
}else if (actionSheet==alertComment) {//alertComment
if (buttonIndex==0) {
}
}
}
Ответ 4
Stack и Guillermo Ortega ответ, вероятно, то, что вы бы использовали с несколькими UIAlertView, но не на десять. Я использую BlocksKit, который похож на материал Lambda, что и предложила душа. Это тоже хороший вариант, хотя, если у вас слишком много вложенных блоков, вы начнете видеть его недостатки (помимо того, что вы будете полагаться в другой библиотеке).
Обычным способом обработки нескольких вещей было бы иметь объект обработчика. (
@interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end
), сделайте этот объект делегатом представления предупреждения и убедитесь, что объект жив как минимум до тех пор, пока не будет отклонен вид предупреждения.
Это, безусловно, будет работать, но может быть слишком много работы...
Далее следует то, что я придумал; ИМО проще, и нет необходимости в какой-либо третьей библиотеке сторонних разработчиков или ivar на UIAlertView. Только один дополнительный объект (@property (nonatomic, strong) NSArray *modalActions
) для хранения действий, которые текущий UIAlertView вызовет для выполнения
Отображение UIAlertView и реагирование соответственно
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:alertTitle
message:@"Blah blah"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:b1, b2, b3, nil];
// Add one selector/action per button at the proper index
self.modalActions = @[
[NSNull null], // Because indexes of UIAlertView buttons start at 1
NSStringFromSelector(@selector(actionForAlertViewButton1)),
NSStringFromSelector(@selector(actionForAlertViewButton2)),
NSStringFromSelector(@selector(actionForAlertViewButton3))];
[alertView show];
Метод делегата:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.cancelButtonIndex != buttonIndex) {
[self performModalActionAtIndex:buttonIndex];
}
}
Часть, которая фактически выполняет действие:
- (void)performModalActionAtIndex:(NSInteger)index
{
if (-1 < index && index < self.modalActions.count &&
[self.modalActions[index] isKindOfClass:[NSString class]]) {
SEL action = NSSelectorFromString(self.modalActions[index]);
NSLog(@"action: %@", self.modalActions[index]);
if ([self respondsToSelector:action]) {
// There is a situation with performSelector: in ARC.
// http://stackoverflow.com/questions/7017281/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:action];
#pragma clang diagnostic pop
}
self.modalActions = nil;
}
Повторное использование для UIActionSheets тоже
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
delegate:self
cancelButtonTitle:cancelButton
destructiveButtonTitle:nil
otherButtonTitles:button1, button2, button3, nil];
// Similarly, add one action per button at the proper index
self.modalActions = @[
NSStringFromSelector(@selector(actionForActionSheetButton1)),
NSStringFromSelector(@selector(actionForActionSheetButton2)),
NSStringFromSelector(@selector(actionForActionSheetButton3))];
Метод делегата:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (actionSheet.cancelButtonIndex != buttonIndex) {
[self performModalActionAtIndex:buttonIndex];
}
}
Почему это работает:
Это работает по двум причинам:
Во-первых, я никогда не представляю два UIAlertView, у которых есть делегат одновременно. (ИМО вы не должны, это выглядит не очень хорошо). Во-вторых, поскольку в моем случае (как 90% случаев) целью действий всегда является один и тот же объект (в данном случае: self
). Даже если вы не выполняете вышеуказанные условия, вы можете даже использовать этот подход с некоторыми изменениями:
-
Если вы одновременно показываете два или более UIAlerViews или UIActionSheets (возможно в iPad), используйте словарь для хранения одного массива действий, связанных с определенным UIAlertView/UIActionSheet.
-
Если целью действий не является self
, вам нужно сохранить пары (цель и действие) в массиве. (Что-то, чтобы имитировать UIButtons addTarget:action:...
).
В любом случае для хранения целевого и/или UIActionSheet/UIAlertView [NSValue valueWithNonretainedObject:]
должно быть удобно:)
Ответ 5
First of all you declare UIAlertViewDelegate in .h file after put below code in .m file
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
//put button action which you want.
}
}
Ответ 6
Внедрить UIAlertViewDelegate
и использовать метод делегата
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0) {
// Do something
}
else {
// Do something
}
}
Ответ 7
UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"Data Saved" message:@"Choose more photos" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:Nil];
[alertView show];
[alertView release];
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex==0)
{
[self dismissModalViewControllerAnimated:YES];
}
}
Ответ 8
в быстрой:
мы можем использовать этот небольшой блок кода
let alert = UIAlertController(title: "Alert", message: "This is an alert message", preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {(action:UIAlertAction) in print("This is in alert block")
})
alert.addAction(action)
self.presentViewController(alert, animated: true, completion: nil)