2009-09-08 78 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 
    
    相關問題