푸시된 컨트롤러에서 루트뷰 컨트롤러를 가져오려면 어떻게 해야 합니까?
RootViewController에서 다음과 같은 보기 컨트롤러를 푸시합니다.
[self.navigationController pushViewController: 다른 ViewController 애니메이션:예];
그러나, 시작anotherViewController
이제 RootView 컨트롤러에 다시 액세스하려고 합니다.
난 노력하고 있어.
(지금 다른 View 컨트롤러 내부)///RootViewController *root = (RootViewController*)self.parentViewController ; // 아니요.잘못한RootViewController *root = (RootViewController*)[self.navigationController.viewController 개체 At색인:0] ; // YES!!그건 효과가 있다.
저는 이것이 왜 효과가 있는지 그리고 그것을 하는 가장 좋은 방법인지 확신할 수 없습니다.RootViewController의 탐색 컨트롤러에 푸시한 컨트롤러에서 RootViewController를 가져오는 더 나은 방법과 내가 한 방식이 신뢰할 수 있는지 여부에 대해 누군가 의견을 말해줄 수 있습니까?
빠른 버전:
var rootViewController = self.navigationController?.viewControllers.first
목표 C 버전:
UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];
여기서 self는 UI 탐색 컨트롤러에 내장된 UI View 컨트롤러의 인스턴스입니다.
UI 탐색 컨트롤러의 viewControllers 속성을 사용합니다.코드 예제:
// Inside another ViewController
NSArray *viewControllers = self.navigationController.viewControllers;
UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];
이것이 "뒤로" 보기 컨트롤러를 가져오는 표준 방법입니다.이유objectAtIndex:0
액세스하려는 뷰 컨트롤러도 루트 컨트롤러이기 때문에 작동합니다. 탐색 깊이가 더 깊으면 백 뷰가 루트 뷰와 동일하지 않을 수 있습니다.
거의 모든 답변에 언급된 동일한 것의 약간 덜 추한 버전:
UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];
당신의 경우, 저는 아마 다음과 같은 일을 할 것입니다.
UINavigationController 하위 클래스 내:
- (UIViewController *)rootViewController
{
return [[self viewControllers] firstObject];
}
그러면 다음을 사용할 수 있습니다.
UIViewController *rootViewController = [self.navigationController rootViewController];
편집을
OP가 댓글에 속성을 요청했습니다.
당신이 원한다면, 당신은 다음과 같은 것을 통해 이것에 접근할 수 있습니다.self.navigationController.rootViewController
읽기 전용 속성을 헤더에 추가하기만 하면 됩니다.
@property (nonatomic, readonly, weak) UIViewController *rootViewController;
빠른 확장에 관심이 있는 모든 분들을 위해, 제가 지금 사용하고 있는 것은 다음과 같습니다.
extension UINavigationController {
var rootViewController : UIViewController? {
return self.viewControllers.first
}
}
@dullgan의 답변에 덧붙여, 그것은 항상 사용하기 좋은 접근법입니다.firstObject
위에objectAtIndex:0
왜냐하면 첫 번째는 배열에 객체가 없으면 0을 반환하지만, 후자는 예외를 던지기 때문입니다.
UIViewController *rootViewController = self.navigationController.rootViewController;
또는 다음과 같은 범주를 만드는 것이 좋습니다.UINavigationController+Additions
거기서 당신의 방법을 참조하십시오.
@interface UINavigationController (Additions)
- (UIViewController *)rootViewController;
@end
@implementation UINavigationController (Additions)
- (UIViewController *)rootViewController
{
return self.viewControllers.firstObject;
}
@end
저는 이상한 상황에 직면합니다.
self.viewControllers.first
항상 루트 뷰 컨트롤러는 아닙니다.
일적으로.self.viewControllers.first
는 rootviewController 입니다.하지만 가끔은 그렇지 않습니다.
class MyCustomMainNavigationController: UINavigationController {
function configureForView(_ v: UIViewController, animated: Bool) {
let root = self.viewControllers.first
let isRoot = (v == root)
// Update UI based on isRoot
// ....
}
}
extension MyCustomMainNavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController,
willShow viewController: UIViewController,
animated: Bool) {
self.configureForView(viewController, animated: animated)
}
}
내 문제:
일적으로.self.viewControllers.first
이라root
viewController.하지만, 내가 전화할 때.popToRootViewController(animated:)
그리고 나서 그것은 촉발됩니다.navigationController(_:willShow:animated:)
지금이순간,순간▁at이▁this,지,self.viewControllers.first
루트 뷰 컨트롤러가 아니라 사라질 마지막 뷰 컨트롤러입니다.
요약
self.viewControllers.first
항상 그렇지는 않습니다.root
viewController.때로는 마지막 뷰 컨트롤러가 될 수도 있습니다.
그래서, 나는 계속하는 것을 제안합니다.rootViewController
에 self.viewControllers
보기 컨트롤러가 하나만 있습니다.에 있습니다.viewDidLoad()
사용자 지정 UINavigation 컨트롤러의
class MyCustomMainNavigationController: UINavigationController {
fileprivate var myRoot: UIViewController!
override func viewDidLoad() {
super.viewDidLoad()
// My UINavigationController is defined in storyboard.
// So at this moment,
// I can get root viewController by `self.topViewController!`
let v = self.topViewController!
self.myRoot = v
}
}
환경:
- iOS 14.0.1이 설치된 아이폰 7
- Xcode 12.0.1(12A7300)
UIA 애플리케이션 싱글톤에 키Windows를 요청하고 UIWindow에서 루트뷰 컨트롤러(rootViewController 속성)를 요청하는 것은 어떻습니까?
UIViewController root = [[[UIApplication sharedApplication] keyWindow] rootViewController];
여기서 저는 어떤 장소에서 뿌리까지 탐색할 수 있는 보편적인 방법을 생각해냈습니다.
이 클래스로 새 클래스 파일을 만들면 프로젝트의 모든 위치에서 액세스할 수 있습니다.
import UIKit class SharedControllers { static func navigateToRoot(viewController: UIViewController) { var nc = viewController.navigationController // If this is a normal view with NavigationController, then we just pop to root. if nc != nil { nc?.popToRootViewControllerAnimated(true) return } // Most likely we are in Modal view, so we will need to search for a view with NavigationController. let vc = viewController.presentingViewController if nc == nil { nc = viewController.presentingViewController?.navigationController } if nc == nil { nc = viewController.parentViewController?.navigationController } if vc is UINavigationController && nc == nil { nc = vc as? UINavigationController } if nc != nil { viewController.dismissViewControllerAnimated(false, completion: { nc?.popToRootViewControllerAnimated(true) }) } } }
프로젝트 내 어디서나 사용:
{ ... SharedControllers.navigateToRoot(self) ... }
이것은 저에게 효과가 있었습니다.
루트 뷰 컨트롤러가 탐색 컨트롤러에 내장된 경우:
UINavigationController * navigationController = (UINavigationController *)[[[[UIApplication sharedApplication] windows] firstObject] rootViewController];
RootViewController * rootVC = (RootViewController *)[[navigationController viewControllers] firstObject];
하세요.keyWindow
사용되지 않습니다.
언급URL : https://stackoverflow.com/questions/1792858/how-do-i-get-the-rootviewcontroller-from-a-pushed-controller
'programing' 카테고리의 다른 글
mariadb 온라인 삭제 인덱스가 작동하지 않음 (0) | 2023.06.13 |
---|---|
Oracle Text는 NVARCHAR2에서 작동하지 않습니다.그 밖에 어떤 것을 사용할 수 없습니까? (0) | 2023.06.13 |
wp_query에서 복잡한 계산 또는 조건부 필드로 주문하려면 어떻게 해야 합니까? (0) | 2023.06.13 |
내 Git repo가 분리된 HEAD 상태에 들어간 이유는 무엇입니까? (0) | 2023.06.13 |
정의되지 않은 함수 convert_to_screen() 호출 (0) | 2023.06.13 |