답변:
다음을 사용할 수 있습니다.
- (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");
}
}
물론 viewinillDisappear가 호출 될 때까지 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 가지 방법은 뷰 컨트롤러의 모양 콜백에서 하위 뷰 컨트롤러로 표시, 해제 또는 추가 또는 제거되는지 여부를 결정하는 데 사용될 수 있습니다. 예를 들어, 뷰 컨트롤러는 뷰 컨트롤러가 해제되었거나 사라져서 사라 졌는지 확인할 수 있습니다. viewWillDisappear : 메소드에서 식 ([self isBeingDismissed] || [self isMovingFromParentViewController])을 확인하여 자신에게 묻는 메시지가 나타납니다. "
- (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]) {
}
}
스위프트 3 버전 :
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed || self.isMovingFromParentViewController {
}
}
이것에 관한 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에 적용되며 다른 iOS 에 적용되는지 전혀 모릅니다. 내가 아는 것에서 viewDidDisappear
,보기에서 이미 팝되었습니다. 이는 쿼리 self.navigationController.viewControllers
할 때을 얻는다는 의미 nil
입니다. 그래서 그것이 아닌지 확인하십시오.
TL; DR
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if (self.navigationController.viewControllers == nil) {
// It has been popped!
NSLog(@"Popped and Gone");
}
}
Segues는 iOS 6 이상에서이 문제를 처리하는 매우 효과적인 방법입니다. 인터페이스 빌더에서 특정 segue에 식별자를 부여한 경우에서 확인할 수 있습니다 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
}
}
감사합니다 @Bryan Henry, 여전히 Swift 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