我有一个视图,带有一个导航控制器管理的后退按钮,我想检查用户单击后退按钮时是否保存了文件。 如果文件已保存,则返回上一个视图,否则uialertview会询问您是否要保存该文件。iphone navigationController:在退出当前视图之前等待uialertview响应
所以我做到了,但视图disapear和alertview后出现。
我有一个视图,带有一个导航控制器管理的后退按钮,我想检查用户单击后退按钮时是否保存了文件。 如果文件已保存,则返回上一个视图,否则uialertview会询问您是否要保存该文件。iphone navigationController:在退出当前视图之前等待uialertview响应
所以我做到了,但视图disapear和alertview后出现。
当viewWillDisappear被调用时,已经太晚了。你应该在之前拦截后退按钮。我从来没有做过,但我的建议是设置上的导航栏属性代表在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];
您必须继承UINavigationController以使其工作。然后覆盖 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)项目。 您应该设置视图控制器采用的自定义委托协议,如果允许它弹出,请调用您的[super navigationBar shouldPopItem:],否则返回上述方法的NO。
我已经实现了这一点,并可以验证它是否工作,在我看来是最简单的方法来完成此操作。 – 2011-07-17 23:56:43
那岂不是更容易只是左键项目添加如下所示:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
要跟进诺布雷响应和乔恩mentionned它,最好的办法是子类的UINavigationController。
最简单的方式和以达致这最快的方式:
@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; }
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
听起来合乎逻辑,但你应该保存当前的导航栏在覆盖它之前委托,在你决定弹出之后重置它,甚至可以在显示你的警报之前通过'navigationBar:shouldPopItem:'调用旧的委托(如果不是零)。 – pix0r 2009-09-08 22:29:26
该代码不会出现alertview – Mathieu 2009-09-08 22:33:34
@Mathieu:该方法是否应该调用该方法?如果不是,则可能必须在viewDidAppear方法而不是init方法中设置委托。 pix0r的评论也是有效的。我会更新我的答案以反映这一点。 – 2009-09-08 22:37:47