경고:창 계층 구조에 없는 *에 * 표시 시도 - swift
제가 발표하려고 하는 것은ViewController
데이터 모델에 저장된 데이터가 있는지 확인합니다.그러나 다음 오류가 발생합니다.
경고:보기가 창 계층에 없는 *에 *를 표시하려고 합니다.
관련 코드:
override func viewDidLoad() {
super.viewDidLoad()
loginButton.backgroundColor = UIColor.orangeColor()
var request = NSFetchRequest(entityName: "UserData")
request.returnsObjectsAsFaults = false
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if(results.count <= 0){
print("Inga resultat")
} else {
print("SWITCH VIEW PLOX")
let internVC = self.storyboard?.instantiateViewControllerWithIdentifier("internVC") as internViewController
self.presentViewController(internVC, animated: true, completion: nil)
}
}
저는 구글을 사용하여 찾은 다양한 솔루션을 시도했지만 성공하지 못했습니다.
현재 코드에서 보기 컨트롤러의 보기는 작성되었을 뿐 보기 계층 구조에는 추가되지 않았습니다.가능한 한 빨리 해당 뷰 컨트롤러에서 표시하려면 에서 표시해야 합니다.viewDidAppear
가장 안전하게.
목표 c: mpmovie 플레이어 위에 뷰 컨트롤러를 표시할 때의 문제를 해결했습니다.
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
스위프트 3
저는 이것을 계속 초보자로 떠올렸고 현재 로드 모달 뷰는 무시할 수 있지만 모달을 보여줄 필요가 없다면 루트 컨트롤러로 전환하는 것이 가장 좋습니다.
이거 쓰고 있었어요.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
present(vc, animated: false, completion: nil)
내 탭 컨트롤러에서 대신 사용:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let view = storyboard.instantiateViewController(withIdentifier: "MainAppStoryboard") as UIViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
//show window
appDelegate.window?.rootViewController = view
여러 스토리보드 화면을 전환해야 하는 경우 보기 컨트롤러를 조정하면 됩니다.
스위프트 3.
이 함수를 호출하여 맨 위의 보기 컨트롤러를 가져온 다음 해당 보기 컨트롤러를 표시합니다.
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
용도:
let topVC = topMostController()
let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
topVC.present(vcToPresent, animated: true, completion: nil)
SWIFT용
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
지연이 발생한 셀렉터만 수행하면 됩니다(0초 작동).
override func viewDidLoad() {
super.viewDidLoad()
perform(#selector(presentExampleController), with: nil, afterDelay: 0)
}
@objc private func presentExampleController() {
let exampleStoryboard = UIStoryboard(named: "example", bundle: nil)
let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC
present(exampleVC, animated: true)
}
스위프트 4
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
메인 스레드를 사용하여 뷰 컨트롤러를 표시하거나 해제하는 것이 저에게 효과가 있었습니다.
DispatchQueue.main.async { self.present(viewController, animated: true, completion: nil) }
사용자가 딥 링크를 연 후 컨트롤러를 제시하는 동안 이 오류가 발생했습니다.이것이 최선의 해결책이 아니라는 것을 알지만, 만약 당신이 짧은 시간 안에 있다면 여기에 빠른 해결책이 있습니다 - 코드를 랩으로 감으세요.asyncAfter
:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in
navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion)
})
프레젠테이션 컨트롤러가 전화를 걸 시간을 줍니다.viewDidAppear
.
let storyboard = UIStoryboard(name: "test", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "teststoryboard") as UIViewController
UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
이것은 그것이 가장 높은 뷰를 확실히 하기 위해 효과가 있는 것처럼 보였습니다.
오류가 발생했습니다.
경고:myapp.testController: 0x7fdd01703990을 myapp.testController: 0x7fd01703690의 보기가 창 계층에 없습니다!
이것이 빠른 3으로 다른 사람들에게 도움이 되기를 바랍니다.
신속한 3.0 이상의 경우
public static func getTopViewController() -> UIViewController?{
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
return topController
}
return nil}
Swift 5.1:
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let mainViewController = storyboard.instantiateViewController(withIdentifier: "ID")
let appDeleg = UIApplication.shared.delegate as! AppDelegate
let root = appDeleg.window?.rootViewController as! UINavigationController
root.pushViewController(mainViewController, animated: true)
나는 많은 접근법을 시도해 왔습니다! 유일하게 유용한 것은:
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
}
여기 topViewController에 대한 모든 구현이 다음과 같은 경우를 완전히 지원하지는 않습니다.UINavigationController
또는UITabBarController
이 두 가지의 경우 약간 다른 처리가 필요합니다.
위해서UITabBarController
그리고.UINavigationController
다른 구현이 필요합니다.
다음은 상위 MostViewController를 가져오는 데 사용하는 코드입니다.
protocol TopUIViewController {
func topUIViewController() -> UIViewController?
}
extension UIWindow : TopUIViewController {
func topUIViewController() -> UIViewController? {
if let rootViewController = self.rootViewController {
return self.recursiveTopUIViewController(from: rootViewController)
}
return nil
}
private func recursiveTopUIViewController(from: UIViewController?) -> UIViewController? {
if let topVC = from?.topUIViewController() { return recursiveTopUIViewController(from: topVC) ?? from }
return from
}
}
extension UIViewController : TopUIViewController {
@objc open func topUIViewController() -> UIViewController? {
return self.presentedViewController
}
}
extension UINavigationController {
override open func topUIViewController() -> UIViewController? {
return self.visibleViewController
}
}
extension UITabBarController {
override open func topUIViewController() -> UIViewController? {
return self.selectedViewController ?? presentedViewController
}
}
앞의 답변은 1) 보기를 제공해야 하는 보기 컨트롤러가 아직 보기 계층에 추가되지 않았거나 2) 보기 컨트롤러가 최상위 보기 컨트롤러가 아닌 상황과 관련이 있습니다.
또 다른 가능성은 다른 경고가 이미 표시되어 있고 아직 해제되지 않은 상태에서 경고를 표시해야 한다는 것입니다.
Swift Method(Swift Method), 데모를 제공합니다.
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
func demo() {
let vc = ViewController()
let nav = UINavigationController.init(rootViewController: vc)
topMostController().present(nav, animated: true, completion: nil)
}
Top View 컨트롤러를 찾는 대신 사용할 수 있습니다.
viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext
viewController가 표시할 컨트롤러인 경우 탭바, NavBar와 같은 계층 구조에 다른 종류의 보기가 있을 때 유용합니다. 다른 보기는 올바르지만 좀 더 해커적입니다.
다른 프레젠테이션 스타일은 애플 문서에서 찾을 수 있습니다.
언급URL : https://stackoverflow.com/questions/26022756/warning-attempt-to-present-on-whose-view-is-not-in-the-window-hierarchy-s
'source' 카테고리의 다른 글
요소 인덱스를 상위 요소에 대한 하위 요소로 가져옵니다. (0) | 2023.09.04 |
---|---|
MySql 트랜잭션은 콘솔에서만 작동합니다. (0) | 2023.09.04 |
regexp 파라미터로 SELECT를 수신하면 교대로만 작동합니다(홀수 시간만). (0) | 2023.09.04 |
JSON.parse()가 작동하지 않습니다. (0) | 2023.09.04 |
파워셸 최대/첫 번째/두 번째 기능 (0) | 2023.09.04 |