iphone navigationController :在退出当前视图之前等待 uialertview 响应

发布于 2024-08-04 00:52:05 字数 675 浏览 3 评论 0原文

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

I have a view with a back button managed with a navigation controller and I want to check if a file has been saved when the user click on the back button.
If the file has been saved you go back in the previous view, else a uialertview ask you if you want to save the file or not.

So I did that but the view disapear and the alertview appear after.

-(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;
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

百合的盛世恋 2024-08-11 00:52:05

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

When viewWillDisappear is called, it's already too late. You should intercept the back button earlier on. I have never done it, but my suggestion is to set the delegate on the navigationBar property in your viewDidAppear method:

// save the previous delegate (create an ivar for that)
prevNavigationBarDelegate = self.navigationController.navigationBar.delegate;

self.navigationController.navigationBar.delegate = self;

Don't forget to set it back in viewWillDisappear:

self.navigationController.navigationBar.delegate = prevNavigationBarDelegate;

Then intercept the shouldPopItem method:

- (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; 
}

And in the YES handler for the dialog, manually pop the controller:

[self.navigationController popViewController:YES];
千寻… 2024-08-11 00:52:05

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

You must subclass UINavigationController for this to work. Then override - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item .
You should set up a custom Delegate protocol that your view controllers adopt and, if you allow it to pop, call your [super navigationBar shouldPopItem:], else, return NO to the above method.

并安 2024-08-11 00:52:05

添加一个左按钮项目不是更容易吗?如下所示:

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

Wouldn't it be easier just to add a left button item as in the following:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
我爱人 2024-08-11 00:52:05

要跟进 nobre 响应,正如 Jon 提到的,最好的方法是子类化 UINavigationController。

实现此目的的最简单和最快的方法:

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

自定义导航类

  1. 在 UIViewController 中实现 CustomNavigationControllerDelegate 协议

@interface YourViewController

#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)动画
{
((CustomNavigationController*)self.navigationController).customDelegate = self;
最后

  1. 中自行弹出控制器

也是重要的部分,删除委托(以避免在弹出时重新触发自己)并在 UIAlertViewDelegate case kpopup_back :
{
if(buttonIndex != 0) //确定
{
((CustomNavigationController*)self.navigationController).customDelegate = nil;
[self.navigationController popViewControllerAnimated:YES];
}
}

在我这边完美地工作,希望它能有所帮助。


以下是来源:

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

To follow up on nobre response and as Jon mentionned it, the best way is to subclass UINavigationController.

The easiest way and fastest way to acheive this :

  1. Modify the class of your navigation controller in Interface Builder to inherit from CustomNavigationControllerDelegate

Custom navigation class

  1. Implement the CustomNavigationControllerDelegate protocol in your 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;
}
  1. Register your controller as the delegate

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

  1. Finally and important part, REMOVE the delegate (to avoid to re-trigger yourself on the pop) and pop the controller yourself in the the UIAlertViewDelegate

case kpopup_back :
{
if(buttonIndex != 0) //OK
{
((CustomNavigationController*)self.navigationController).customDelegate = nil;
[self.navigationController popViewControllerAnimated:YES];
}
}
break;

It works flawlessly on my side, hope it can help.


Here are the sources :

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文