アクションを実行できるように、View Controllerがnavスタックからポップされようとしていることを知る必要があります。
-viewWillDisappearを使用することはできません。これは、何らかの理由でView Controllerが画面外に移動したときに呼び出されるためです(新しいView Controllerが一番上にプッシュされるなど)。
コントローラーがいつポップされるのかを具体的に知る必要があります。
事前に感謝します。
これには明示的なメッセージはないと思いますが、UINavigationControllerをサブクラス化してpopViewControllerAnimatedをオーバーライドできます(自分でこれを試したことはありませんが)。
あるいは、View Controllerへの他の参照がない場合、その-deallocに追加できますか?
提示されたVCでviewWillDisappear
メソッドをオーバーライドし、オーバーライド内でisMovingFromParentViewController
フラグを確認して、特定のロジックを実行します。私の場合、Navigation Controllerのツールバーを隠しています。それでも、提示されたVCは完璧ではないがプッシュされたことを理解する必要があります。
UIViewController
のカスタムサブクラスで willMoveToParentViewController:
(viewWillDisappear:
の代わりに)をオーバーライドしてみてください。
View ControllerがコンテナView Controllerに追加または削除される直前に呼び出されます。
- (void)willMoveToParentViewController:(UIViewController *)parent
{
[super willMoveToParentViewController:parent];
if (!parent) {
// `self` is about to get popped.
}
}
幸い、viewWillDisappearメソッドが呼び出されるまでに、viewControllerは既にスタックから削除されているため、viewControllerがself.navigationController.viewControllers
Swift 4
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let nav = self.navigationController {
let isPopping = !nav.viewControllers.contains(self)
if isPopping {
// popping off nav
} else {
// on nav, not popping off (pushing past, being presented over, etc.)
}
} else {
// not on nav at all
}
}
オリジナルコード
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ((self.navigationController) &&
(![self.navigationController.viewControllers containsObject:self])) {
NSLog(@"I've been popped!");
}
}
これは私のために働いています。
- (void)viewDidDisappear:(BOOL)animated
{
if (self.parentViewController == nil) {
NSLog(@"viewDidDisappear doesn't have parent so it's been popped");
//release stuff here
} else {
NSLog(@"PersonViewController view just hidden");
}
}
ここでキャッチできます。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (viewController == YourAboutToAppearController) {
// do something
}
}
これは、新しいビューが表示される直前に発生します。まだ誰も動いていない。私はいつもasinine NavigationControllerの前で魔法をかけます。タイトルとボタンのタイトルを設定し、そこで何でもできます。
私は同じ問題を抱えています。 viewDisDisappearで試しましたが、関数getがありません:((おそらく、私のVCがすべてUITableViewControllerであるためかわかりません。)Alexの提案はうまく機能しますが、Navigation Controllerこの場合、navコントローラーのすべてのVCには、サブクラス化したナビゲーションコントローラーではなく、UIMoreNavigationControllerとしてnavigationControllerがあるため、VCが間もなく通知されることはありません。ポップ。
最後に、UINavigationControllerのカテゴリの問題を解決し、書き直します-(UIViewController *)popViewControllerAnimated:(BOOL)animated
- (UIViewController *)popViewControllerAnimated:(BOOL)animated{
NSLog(@"UINavigationController(Magic)");
UIViewController *vc = self.topViewController;
if ([vc respondsToSelector:@selector(viewControllerWillBePopped)]) {
[vc performSelector:@selector(viewControllerWillBePopped)];
}
NSArray *vcs = self.viewControllers;
UIViewController *vcc = [vcs objectAtIndex:[vcs count] - 2];
[self popToViewController:vcc animated:YES];
return vcc;}
それは私にとってうまくいく:D
私はこれを試しました:
- (void) viewWillDisappear:(BOOL)animated {
// If we are disappearing because we were removed from navigation stack
if (self.navigationController == nil) {
// YOUR CODE HERE
}
[super viewWillDisappear:animated];
}
アイデアは、ポップ時にView ControllerのnavigationControllerがnilに設定されるということです。そのため、ビューが消え、さらにnavigationControllerがある場合、ポップされたと判断しました。 (他のシナリオでは機能しない場合があります)。
ドキュメントに記載されていないため、popWillDisappearがポップ時に呼び出されることを保証できません。ビューがトップビューで、トップビューの下にあるときに試してみました-そして、両方で機能しました。
頑張って、オーデッド。
UINavigationController
をサブクラス化し、popViewController
をオーバーライドします。
protocol CanPreventPopProtocol {
func shouldBePopped() -> Bool
}
class MyNavigationController: UINavigationController {
override func popViewController(animated: Bool) -> UIViewController? {
let viewController = self.topViewController
if let canPreventPop = viewController as? CanPreventPopProtocol {
if !canPreventPop.shouldBePopped() {
return nil
}
}
return super.popViewController(animated: animated)
}
//important to prevent UI thread from freezing
//
//if popViewController is called by gesture recognizer and prevented by returning nil
//UI will freeze after calling super.popViewController
//so that, in order to solve the problem we should not return nil from popViewController
//we interrupt the call made by gesture recognizer to popViewController through
//returning false on gestureRecognizerShouldBegin
//
//tested on iOS 9.3.2 not others
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
let viewController = self.topViewController
if let canPreventPop = viewController as? CanPreventPopProtocol {
if !canPreventPop.shouldBePopped() {
return false
}
}
return true
}
}
これを使用できます:
if(self.isMovingToParentViewController)
{
NSLog(@"Pushed");
}
else
{
NSLog(@"Popped");
}
([self.navigationController.viewControllers indexOfObject:self] == NSNotFound){//このビューのポップが発生した場合、viewwilldisappearでこのチェックを行ってみてください。 }
UINavigationBarDelegateのnavigationBar:shouldPopItemプロトコルメソッドを使用できます。