나는이 별도 가지고 navigationcontrollers
, 하나 RootViewController
A와 함께 다른 RootViewController
B를
ViewController
C를 A 또는 B의 탐색 스택 으로 푸시 할 수 있습니다.
질문 : 내가 ViewController
C에 있을 때 내가 A 또는 B에 속하는 스택에 있는지 어떻게 알 수 있습니까?
나는이 별도 가지고 navigationcontrollers
, 하나 RootViewController
A와 함께 다른 RootViewController
B를
ViewController
C를 A 또는 B의 탐색 스택 으로 푸시 할 수 있습니다.
질문 : 내가 ViewController
C에 있을 때 내가 A 또는 B에 속하는 스택에 있는지 어떻게 알 수 있습니까?
답변:
UINavigationController
의 viewControllers
속성을 사용할 수 있습니다 .
@property(nonatomic, copy) NSArray *viewControllers
토론 : 루트 뷰 컨트롤러는 어레이의 인덱스 0, 후면 뷰 컨트롤러는 인덱스 n-2, 최상위 컨트롤러는 인덱스 n-1에 있습니다. 여기서 n은 어레이의 항목 수입니다.
https://developer.apple.com/documentation/uikit/uinavigationcontroller
이를 사용하여 루트 뷰 컨트롤러 (배열 인덱스 0에있는 컨트롤러)가 뷰 컨트롤러 A인지 B인지 테스트 할 수 있습니다.
var viewControllers: [UIViewController]
viewControllers.last
viewControllers.last
에는 현재 뷰 컨트롤러가 있습니다. 이전 뷰 컨트롤러를 얻으려면 사용해야합니다.viewControllers[viewControllers.count-2]
다음은 허용되는 답변의 구현입니다.
- (UIViewController *)backViewController
{
NSInteger numberOfViewControllers = self.navigationController.viewControllers.count;
if (numberOfViewControllers < 2)
return nil;
else
return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2];
}
UIViewController
확장 으로 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 함수를 유지할 수 있습니다.
@tjklemz 코드의 신속한 구현 :
var backViewController : UIViewController? {
var stack = self.navigationController!.viewControllers as Array
for (var i = stack.count-1 ; i > 0; --i) {
if (stack[i] as UIViewController == self) {
return stack[i-1] as? UIViewController
}
}
return nil
}
println("backViewController is: \(backViewController.description)")
. 이렇게하면 "UINavigationController : 0x7fcea1d286b0"과 같은 설명이 제공됩니다. 이는 명확하지 않지만 적어도 개체를 식별 할 수 있도록합니다. 내가 말했듯이 정확히 필요한 것이 무엇인지 잘 모르겠습니다 ...
navigationController
메소드를 사용하여 검색하십시오. Apple 사이트의 문서를 참조하십시오 .
navigationController 탐색 컨트롤러 인 상위 또는 조상입니다. (읽기 전용)
@property (비 원자, 읽기 전용, 유지) UINavigationController * navigationController
토론 전용은 뷰 컨트롤러가 스택에있는 경우 탐색 컨트롤러를 반환합니다. 탐색 컨트롤러를 찾을 수없는 경우이 속성은 nil입니다.
가용성 아이폰 OS 2.0 이상에서 사용할 수 있습니다.
죽은 말은 구타를 즐기기 때문에 :)
- (UIViewController *)previousViewController
{
NSArray *vcStack = self.navigationController.viewControllers;
NSInteger selfIdx = [vcStack indexOfObject:self];
if (vcStack.count < 2 || selfIdx == NSNotFound) { return nil; }
return (UIViewController *)[vcStack objectAtIndex:selfIdx - 1];
}
Swift 2.2 구현- UIViewController
확장에 이것을 추가하십시오 . nil
viewcontroller가 rootvc이거나 navigationcontroller가 아닌 경우 안전하다는 의미에서 반환 됩니다.
var previousViewController: UIViewController? {
guard let viewControllers = navigationController?.viewControllers else {
return nil
}
var previous: UIViewController?
for vc in viewControllers{
if vc == self {
break
}
previous = vc
}
return previous
}
가드를 사용하는 Swift와 함께.
extension UIViewController {
func getPreviousViewController() -> UIViewController? {
guard let _ = self.navigationController else {
return nil
}
guard let viewControllers = self.navigationController?.viewControllers else {
return nil
}
guard viewControllers.count >= 2 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
내 확장, 스위프트 3
extension UIViewController {
var previousViewController: UIViewController? {
guard let controllers = navigationController?.viewControllers, controllers.count > 1 else { return nil }
switch controllers.count {
case 2: return controllers.first
default: return controllers.dropLast(2).first
}
}
}
신속한 3의 경우 다음을 수행 할 수 있습니다.
var backtoViewController:UIViewController!
for viewController in (self.navigationController?.viewControllers)!.reversed() {
if viewController is NameOfMyDestinationViewController {
backtoViewController = viewController
}
}
self.navigationController!.popToViewController(backtoViewController, animated: true)
반환하려는 viewController로 "NameOfMyDestinationViewController"를 교체하기 만하면됩니다.