[objective-c] 탐색 스택에서 이전 뷰 컨트롤러를 식별하는 방법

나는이 별도 가지고 navigationcontrollers, 하나 RootViewControllerA와 함께 다른 RootViewControllerB를

ViewControllerC를 A 또는 B의 탐색 스택 으로 푸시 할 수 있습니다.

질문 : 내가 ViewControllerC에 있을 때 내가 A 또는 B에 속하는 스택에 있는지 어떻게 알 수 있습니까?



답변

UINavigationControllerviewControllers속성을 사용할 수 있습니다 .

@property(nonatomic, copy) NSArray *viewControllers

토론 : 루트 뷰 컨트롤러는 어레이의 인덱스 0, 후면 뷰 컨트롤러는 인덱스 n-2, 최상위 컨트롤러는 인덱스 n-1에 있습니다. 여기서 n은 어레이의 항목 수입니다.

https://developer.apple.com/documentation/uikit/uinavigationcontroller

이를 사용하여 루트 뷰 컨트롤러 (배열 인덱스 0에있는 컨트롤러)가 뷰 컨트롤러 A인지 B인지 테스트 할 수 있습니다.


답변

다음은 허용되는 답변의 구현입니다.

- (UIViewController *)backViewController
{
    NSInteger numberOfViewControllers = self.navigationController.viewControllers.count;

    if (numberOfViewControllers < 2)
        return nil;
    else
        return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2];
}


답변

- (UIViewController *)backViewController
{
    NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];

    if ( myIndex != 0 && myIndex != NSNotFound ) {
        return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
    } else {
        return nil;
    }
}


답변

허용되는 답변의보다 일반적인 구현 :

- (UIViewController *)backViewController {
    NSArray * stack = self.navigationController.viewControllers;

    for (int i=stack.count-1; i > 0; --i)
        if (stack[i] == self)
            return stack[i-1];

    return nil;
}

이렇게하면 현재 클래스가 탐색 스택에있는 위치에 관계없이 올바른 “백 뷰 컨트롤러”가 반환됩니다.


답변

확장 으로 tjklemz 코드 의 신속한 구현 :

extension UIViewController {

    func backViewController() -> UIViewController? {
        if let stack = self.navigationController?.viewControllers {
            for(var i=stack.count-1;i>0;--i) {
                if(stack[i] == self) {
                    return stack[i-1]
                }
            }
        }
        return nil
    }
}


답변

다음 은 Swift 3을 지원하도록 조정하는 Prabhu Beeman의 Swift 코드 수정 된 버전입니다 .

extension UIViewController {
    func backViewController() -> UIViewController? {
        if let stack = self.navigationController?.viewControllers {
            for i in (1..<stack.count).reverse() {
                if(stack[i] == self) {
                    return stack[i-1]
                }
            }
        }
        return nil
    }
}


답변

속성 의 n-2요소에 viewControllers액세스하여 상위 뷰 컨트롤러에 액세스합니다.

해당 인스턴스가 있으면 NSStringFromClass()함수 에서 나오는 항목을 로깅하여 유형을 확인할 수 있습니다 . 또는 static const컨트롤러 A와 B에 식별자 문자열을 보관하고 문자열을 출력하는 getter 함수를 유지할 수 있습니다.