3 回答

TA貢獻1784條經驗 獲得超2個贊
根據一些評論,原始答案中的解決方案在iOS 8+中的某些情況下似乎不起作用。如果沒有更多詳細信息,我無法驗證實際情況。
對于那些在那種情況下的人,還有另一種選擇??梢酝ㄟ^覆蓋檢測何時彈出視圖控制器willMove(toParentViewController:)?;舅枷胧窃趐arentis 時彈出視圖控制器nil。
請查看“實現Container View Controller”以了解更多詳細信息。
從iOS 5開始,我發現處理這種情況的最簡單方法是使用新方法- (BOOL)isMovingFromParentViewController:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController) {
// Do your stuff here
}
}
- (BOOL)isMovingFromParentViewController 當您在導航堆棧中推入和彈出控制器時很有意義。
但是,如果要呈現模式視圖控制器,則應- (BOOL)isBeingDismissed改用:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isBeingDismissed) {
// Do your stuff here
}
}
如本問題所述,您可以結合使用以下兩個屬性:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController || self.isBeingDismissed) {
// Do your stuff here
}
}
其他解決方案依賴于的存在UINavigationBar。相反,更喜歡我的方法,因為它使執行任務所需的任務與觸發事件的操作(即按后退按鈕)分離。

TA貢獻1788條經驗 獲得超4個贊
雖然viewWillAppear()和viewDidDisappear() 被當返回按鈕被竊聽叫,它們也被稱為在其他時間。有關更多信息,請參見答案結尾。
使用UIViewController.parent
當借助willMoveToParentViewController(_:)OR 將VC從其父級(NavigationController)中刪除時,最好檢測到后退按鈕didMoveToParentViewController()
如果parent為零,則將視圖控制器從導航堆棧中彈出并關閉。如果parent不為nil,則將其添加到堆棧中并顯示。
// Objective-C
-(void)willMoveToParentViewController:(UIViewController *)parent {
[super willMoveToParentViewController:parent];
if (!parent){
// The back button was pressed or interactive gesture used
}
}
// Swift
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
// The back button was pressed or interactive gesture used
}
}
換出willMove了didMove和檢查self.parent做工作后視圖控制器被駁回。
停止解雇
請注意,如果需要執行某種異步保存,則檢查父級不允許您“暫?!边^渡。為此,您可以實現以下內容。唯一的缺點是,您失去了精美的iOS樣式/動畫后退按鈕。在此處也要小心使用交互式滑動手勢。使用以下內容處理這種情況。
var backButton : UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
// Disable the swipe to make sure you get your chance to save
self.navigationController?.interactivePopGestureRecognizer.enabled = false
// Replace the default back button
self.navigationItem.setHidesBackButton(true, animated: false)
self.backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
self.navigationItem.leftBarButtonItem = backButton
}
// Then handle the button selection
func goBack() {
// Here we just remove the back button, you could also disabled it or better yet show an activityIndicator
self.navigationItem.leftBarButtonItem = nil
someData.saveInBackground { (success, error) -> Void in
if success {
self.navigationController?.popViewControllerAnimated(true)
// Don't forget to re-enable the interactive gesture
self.navigationController?.interactivePopGestureRecognizer.enabled = true
}
else {
self.navigationItem.leftBarButtonItem = self.backButton
// Handle the error
}
}
}
將顯示更多視圖
如果您沒有遇到viewWillAppear viewDidDisappear問題,我們來看一個例子。假設您有三個視圖控制器:
ListVC:事物的表視圖
DetailVC:關于事物的詳細信息
SettingsVC:某些選項
detailVC當您從listVC轉到settingsVC并返回到時,可以跟蹤上的呼叫listVC
列表>詳細信息(按下detailVC)Detail.viewDidAppear<-出現
詳細信息>設置(按下settingsVC)Detail.viewDidDisappear<-消失
然后回頭...
設置>詳細信息(彈出設置 VC)<- Detail.viewDidAppear出現
詳細信息>列表(彈出詳細信息 VC)Detail.viewDidDisappear<-消失
請注意,viewDidDisappear不僅在返回時,而且在前進時,都會多次調用它。對于可能需要的快速操作,但是對于更復雜的操作(例如要保存的網絡呼叫),可能不需要。

TA貢獻1802條經驗 獲得超6個贊
第一種方法
- (void)didMoveToParentViewController:(UIViewController *)parent
{
if (![parent isEqual:self.parentViewController]) {
NSLog(@"Back pressed");
}
}
第二種方法
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
}
[super viewWillDisappear:animated];
}
- 3 回答
- 0 關注
- 807 瀏覽
添加回答
舉報