2009-09-08 189 views

回答

6

当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]; 
+0

听起来合乎逻辑,但你应该保存当前的导航栏在覆盖它之前委托,在你决定弹出之后重置它,甚至可以在显示你的警报之前通过'navigationBar:shouldPopItem:'调用旧的委托(如果不是零)。 – pix0r 2009-09-08 22:29:26

+0

该代码不会出现alertview – Mathieu 2009-09-08 22:33:34

+0

@Mathieu:该方法是否应该调用该方法?如果不是,则可能必须在viewDidAppear方法而不是init方法中设置委托。 pix0r的评论也是有效的。我会更新我的答案以反映这一点。 – 2009-09-08 22:37:47

4

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

+0

我已经实现了这一点,并可以验证它是否工作,在我看来是最简单的方法来完成此操作。 – 2011-07-17 23:56:43

2

那岂不是更容易只是左键项目添加如下所示:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)]; 
self.navigationItem.leftBarButtonItem = backButton; 
[backButton release]; 
+0

我尝试了其他帖子中的所有其他复杂的东西,但这一个工作像一个魅力没有并发症。 – gangt 2012-05-21 05:19:30

+0

同样。如果你有一个导航控制器,并希望你的动作只为一个特定的viewcontroller完成,我相信这是唯一的方法。 – Chris 2014-03-11 17:06:46

0

要跟进诺布雷响应和乔恩mentionned它,最好的办法是子类的UINavigationController。

最简单的方式和以达致这最快的方式:

  1. 修改类在界面生成的导航控制器的从CustomNavigationControllerDelegate继承

Custom navigation class

  • 在您的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; 
    } 
    
  • 注册你的控制器作为代表
  • #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 
    
    相关问题