Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iphone navigationController:等待uialertview响应,然后退出当前视图_Iphone_Objective C_Uinavigationcontroller_Uialertview - Fatal编程技术网

iphone navigationController:等待uialertview响应,然后退出当前视图

iphone navigationController:等待uialertview响应,然后退出当前视图,iphone,objective-c,uinavigationcontroller,uialertview,Iphone,Objective C,Uinavigationcontroller,Uialertview,我有一个用导航控制器管理的带有后退按钮的视图,我想在用户单击后退按钮时检查文件是否已保存。 如果文件已保存,请返回上一个视图,否则uialertview会询问您是否要保存文件 所以我这样做了,但是视图被取消,alertview出现在后面 -(void)viewWillDisappear:(BOOL)animated { if(!self.fileSaved){ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" mess

我有一个用导航控制器管理的带有后退按钮的视图,我想在用户单击后退按钮时检查文件是否已保存。 如果文件已保存,请返回上一个视图,否则uialertview会询问您是否要保存文件

所以我这样做了,但是视图被取消,alertview出现在后面

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

当调用ViewWillEverge时,已经太晚了。您应该在前面截取后退按钮。我从未这样做过,但我的建议是在ViewDidAspect方法中的navigationBar属性上设置委托:

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

self.navigationController.navigationBar.delegate = self;
不要忘记将其设置回ViewWillEnglish:

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; 
}
在对话框的“是”处理程序中,手动弹出控制器:

[self.navigationController popViewController:YES];

您必须子类UINavigationController才能工作。然后重写-(BOOL)导航栏:(UINavigationBar*)导航栏应为选项:(UINavigationItem*)项。
您应该设置视图控制器采用的自定义委托协议,如果允许它弹出,请调用[super navigationBar shouldPopItem:],否则,对上述方法返回“否”。

只需添加一个左按钮项,不是更容易吗,如下所示:

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

为了跟进nobre响应,正如Jon所提到的,最好的方法是将UINavigationController子类化

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

  • 在Interface Builder中修改导航控制器的类以从CustomNavigationControllerDelegate继承
  • 在UIViewController中实现CustomNavigationControllerDelegate协议
  • @界面YourViewController

  • 将控制器注册为代理
  • #pragma标记-视图将出现
    -(无效)视图将显示:(BOOL)动画
    {
    ((CustomNavigationController*)self.navigationController).customDelegate=self;
    }

  • 最后也是重要的一部分,删除委托(以避免在pop上重新触发自己),并在UIAlertViewDelegate中自己弹出控制器
  • case kpopup\u back:
    {
    如果(buttonIndex!=0)//确定
    {
    ((CustomNavigationController*)self.navigationController).customDelegate=nil;
    [self.navigationController PopViewControllerInitiated:是];
    }
    }
    中断

    对我来说,它工作得很完美,希望能有所帮助


    以下是资料来源:

    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
    

    听起来合乎逻辑,但您可能应该在覆盖当前导航栏委托之前保存它,在您决定自己弹出后重置它,甚至可能在显示警报之前通过
    导航栏:shouldPopItem:
    调用旧委托(如果不是nil)。@Mathieu:是否调用了shouldPopItem方法?如果没有,则可能必须在ViewDidAspect方法而不是init方法中设置委托。pix0r的评论也是有效的。我将更新我的答案以反映这一点。如果我在ViewDidDisplay或viewDidLoad中或在init方法中设置委托,则不会调用shouldPopiItem。这有一个问题,因为您无法更改“由导航控制器创建并由该对象管理”的导航栏的委托(根据Apple文档)。通常情况下,UINavigationController是UINavigationBar的委托,因此您可以将UINavigationController子类化,并在那里重写此方法。实际上,我在针对super调用此方法时收到警告(警告re:super可能不会对此作出响应),但它确实有效。我已经实现了这一点,并且可以验证它是否有效,在我看来,这是完成这一点最干净的方法。我尝试了其他帖子中所有其他复杂的东西,但这一个工作起来很有魅力,没有任何复杂之处。同样,如果你有一个导航控制器,并且希望你的操作只需要一个p我相信这是唯一的办法。
    #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
    
    #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