回答:
以下を使用できます。
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
NSLog(@"New view controller was pushed");
} else if ([viewControllers indexOfObject:self] == NSNotFound) {
// View is disappearing because it was popped from the stack
NSLog(@"View controller was popped");
}
}
もちろん、これは可能です。viewWillDisappearが呼び出されるまでに、UINavigationControllerのビューコントローラースタック(viewControllersプロパティを通じて公開)が更新されているためです。
viewWillAppear
、ビューコントローラーがプッシュされているか、その上の何かがポップされているかによって、ViewControllers配列が明らかになっているようです。何か案は?
viewDidLoad
一度しか呼び出されないため、アクションを実行できません。うーん、トリッキーです!
![viewControllers containsObject:self]
代わりにあなたがしなかった理由はあります[viewControllers indexOfObject:self] == NSNotFound
か?スタイルの選択は?
-isMovingFromParentViewController
以下の方法で、ビューが明示的にポップされているかどうかをテストできます。
私は最も簡単な方法だと思います:
- (void)viewWillDisappear:(BOOL)animated
{
if ([self isMovingFromParentViewController])
{
NSLog(@"View controller was popped");
}
else
{
NSLog(@"New view controller was pushed");
}
[super viewWillDisappear:animated];
}
迅速:
override func viewWillDisappear(animated: Bool)
{
if isMovingFromParent
{
print("View controller was popped")
}
else
{
print("New view controller was pushed")
}
super.viewWillDisappear(animated)
}
UIViewController.hのAppleのドキュメントから:
「これらの4つのメソッドをビューコントローラーの外観コールバックで使用して、子ビューコントローラーとして表示、非表示、または追加または削除されているかどうかを判断できます。たとえば、ビューコントローラーは、非表示または式([self isBeingDismissed] || [self isMovingFromParentViewController])をチェックして、viewWillDisappear:メソッドで自分自身に質問することでポップされます。
- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
したがって、これを行うための唯一の文書化された方法は、次の方法です。
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if ([self isBeingDismissed] || [self isMovingFromParentViewController]) {
}
}
Swift 3バージョン:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed || self.isMovingFromParentViewController {
}
}
Swiftの場合:
override func viewWillDisappear(animated: Bool) {
if let navigationController = self.navigationController {
if !contains(navigationController.viewControllers as! Array<UIViewController>, self) {
}
}
super.viewWillDisappear(animated)
}
これに関するAppleのドキュメントは理解しにくいと思います。この拡張機能は、各ナビゲーションの状態を確認するのに役立ちます。
extension UIViewController {
public func printTransitionStates() {
print("isBeingPresented=\(isBeingPresented)")
print("isBeingDismissed=\(isBeingDismissed)")
print("isMovingToParentViewController=\(isMovingToParentViewController)")
print("isMovingFromParentViewController=\(isMovingFromParentViewController)")
}
}
この質問はかなり古いですが、偶然見たので、ベストプラクティスを投稿したいと思います(afaik)
あなたはただすることができます
if([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
// view controller popped
}
これはiOS7に適用され、他のiOS7に適用されるかどうかはわかりません。私が知っていることからviewDidDisappear
、ビューではすでにポップされています。つまり、クエリを実行self.navigationController.viewControllers
するとを取得しnil
ます。したがって、それがnilかどうかを確認してください。
TL; DR
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if (self.navigationController.viewControllers == nil) {
// It has been popped!
NSLog(@"Popped and Gone");
}
}
セグエは、iOS 6以降でこの問題を処理する非常に効果的な方法です。Interface Builderで特定のセグエに識別子を指定している場合は、で確認できますprepareForSegue
。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"LoginSegue"]) {
NSLog(@"Push");
// Do something specific here, or set a BOOL indicating
// a push has occurred that will be checked later
}
}
おかげで@ブライアンヘンリー、まだスウィフト5で動作します
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let controllers = navigationController?.children{
if controllers.count > 1, controllers[controllers.count - 2] == self{
// View is disappearing because a new view controller was pushed onto the stack
print("New view controller was pushed")
}
else if controllers.firstIndex(of: self) == nil{
// View is disappearing because it was popped from the stack
print("View controller was popped")
}
}
}
これはsbrocketの答えと同じことを達成するためのカテゴリです:
ヘッダ:
#import <UIKit/UIKit.h>
@interface UIViewController (isBeingPopped)
- (BOOL) isBeingPopped;
@end
ソース:
#import "UIViewController+isBeingPopped.h"
@implementation UIViewController (isBeingPopped)
- (BOOL) isBeingPopped {
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
return NO;
} else if ([viewControllers indexOfObject:self] == NSNotFound) {
return YES;
}
return NO;
}
@end