Iphone navigationController: дождитесь ответа uialertview перед тем, как выйти из текущего представления
У меня есть представление с кнопкой "Назад", управляемой контроллером навигации, и я хочу проверить, был ли файл сохранен, когда пользователь нажимает кнопку "Назад".
Если файл был сохранен, вы вернетесь в предыдущее представление, иначе uialertview спросит вас, хотите ли вы сохранить файл или нет.
Итак, я сделал это, но вид исчез, и появится предупреждение.
-(void)viewWillDisappear:(BOOL)animated {
if(!self.fileSaved){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Save the file?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil];
[alert show];
[alert release];
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0:
NSLog(@"NO");
break;
case 1:
NSLog(@"yes");
break;
default:
break;
}
}
Ответы
Ответ 1
Когда вызывается viewWillDisappear, это уже слишком поздно. Вы должны перехватить кнопку "Назад" ранее. Я никогда этого не делал, но мое предложение состоит в том, чтобы установить делегат в свойстве navigationBar в методе viewDidAppear:
// save the previous delegate (create an ivar for that)
prevNavigationBarDelegate = self.navigationController.navigationBar.delegate;
self.navigationController.navigationBar.delegate = self;
Не забудьте установить его обратно в viewWillDisappear:
self.navigationController.navigationBar.delegate = prevNavigationBarDelegate;
Затем перехватите метод shouldPopItem:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
if(!self.fileSaved) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Save the file?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil];
[alert show];
[alert release];
return NO;
}
if ([prevNavigationBarDelegate respondsToSelector:@selector(navigationBar:shouldPopItem:)])
return [prevNavigationBarDelegate navigationBar:navigationBar shouldPopItem:item];
return YES;
}
И в обработчике YES для диалога вручную введите контроллер:
[self.navigationController popViewController:YES];
Ответ 2
Для этого необходимо подклассифицировать UINavigationController. Затем переопределить - (BOOL) navigationBar: (UINavigationBar *) navigationBar shouldPopItem: (UINavigationItem *) item.
Вы должны настроить пользовательский протокол делегирования, который будут приняты вашими контроллерами представлений, и, если вы позволите ему поп, вызвать ваш [super navigationBar shouldPopItem:], иначе вернуть НЕТ указанному выше методу.
Ответ 3
Не было бы проще просто добавить элемент левой кнопки, как показано ниже:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
Ответ 4
Чтобы следить за благородным ответом, и, как пояснил Джон, лучший способ - подкласс UINavigationController.
Самый простой способ и быстрый способ добиться этого:
- Измените класс вашего контроллера навигации в Interface Builder, чтобы наследовать от CustomNavigationControllerDelegate
![Пользовательский класс навигации]()
- Внедрить протокол CustomNavigationControllerDelegate в вашем UIViewController
@interface YourViewController <CustomNavigationControllerDelegate>
#pragma mark - UINavigationBar Delegate Methods
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancel otherButtonTitles:ok, nil];
alert.tag = kpopup_back;
[alert show];
return NO;
}
- Зарегистрируйте свой контроллер в качестве делегата
#pragma mark - viewWillAppear
- (void) viewWillAppear:(BOOL)animated
{
((CustomNavigationController*)self.navigationController).customDelegate = self;
}
- Наконец-то и важная часть, УДАЛИТЕ делегата (чтобы избежать повторного запуска самого себя в поп-музыке) и поместите контроллер самостоятельно в UIAlertViewDelegate
case kpopup_back :
{
if(buttonIndex != 0) //OK
{
((CustomNavigationController*)self.navigationController).customDelegate = nil;
[self.navigationController popViewControllerAnimated:YES];
}
}
break;
Он работает безупречно на моей стороне, надеюсь, что это может помочь.
Вот источники:
CustomNavigationControllerDelegate.h
#import <UIKit/UIKit.h>
@protocol CustomNavigationControllerDelegate <NSObject>
@optional
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
@end
@interface CustomNavigationController : UINavigationController
@property (nonatomic, retain) id<CustomNavigationControllerDelegate> customDelegate;
@end
CustomNavigationControllerDelegate.m
#import "CustomNavigationController.h"
@interface CustomNavigationController ()
@end
@implementation CustomNavigationController
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
if (_customDelegate && [_customDelegate respondsToSelector:@selector(navigationBar:shouldPopItem:)]) {
return [_customDelegate navigationBar:navigationBar shouldPopItem:item];
}
return YES;
}
@end