6

我有一个带有导航控制器管理的后退按钮的视图,我想检查用户单击后退按钮时是否保存了文件。如果文件已保存,则返回上一个视图,否则 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;
}
}
4

4 回答 4

6

当 viewWillDisappear 被调用时,已经太晚了。您应该更早地拦截后退按钮。我从未这样做过,但我的建议是在您的 viewDidAppear 方法中的 navigationBar 属性上设置委托:

// 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];
于 2009-09-08T22:18:26.480 回答
4

您必须继承 UINavigationController 才能使其工作。然后覆盖 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item 。您应该设置您的视图控制器采用的自定义 Delegate 协议,如果您允许它弹出,请调用您的 [super navigationBar shouldPopItem:],否则,向上述方法返回 NO。

于 2010-05-11T16:44:43.563 回答
2

像下面这样添加一个左键项不是更容易吗:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
于 2011-10-30T23:24:37.883 回答
0

为了跟进 nobre 响应,正如 Jon 提到的那样,最好的方法是继承 UINavigationController。

实现这一目标的最简单方法和最快方法:

  1. 在 Interface Builder 中修改导航控制器的类以从 CustomNavigationControllerDelegate 继承

自定义导航类

  1. 在你的 UIViewController 中实现 CustomNavigationControllerDelegate 协议

@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;
}
  1. 将您的控制器注册为代表

#pragma mark - viewWillAppear - (void) viewWillAppear:(BOOL)animated { ((CustomNavigationController*)self.navigationController).customDelegate = self; }

  1. 最后也是重要的部分,删除委托(以避免在弹出时重新触发自己)并自己在 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
于 2015-12-17T10:36:42.117 回答