Swift导航控制器在尝试导航到另一个视图控制器时返回nil。

huangapple go评论78阅读模式
英文:

swift navigation controller return nil when trying to navigate to another View Controller

问题

我们有一个Router类来导航视图控制器到另一个视图控制器,它按预期工作,但随机地视图控制器堆栈变为nil,导致崩溃。我们尝试使用"if let"来避免崩溃,但问题在于当viewControllersStack为nil时会出现黑屏。所以我们已经恢复了它。您能建议导航堆栈为什么为nil,如果导航为nil应该如何处理?

private func PopOrPushToViewController(_ strControllerClass: String) {
    
    // 获取堆栈中的控制器列表
    let viewControllersStack: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]
    var boolDidNaviagtion = false
    for viewController in viewControllersStack {
        if boolDidNaviagtion {
            viewController.removeFromParent()
        }
        if String(describing: type(of: viewController)) == strControllerClass {
            boolDidNaviagtion = true
            self.navigationController?.popToViewController(viewController, animated: true)
        }
    }
    if !boolDidNaviagtion {
        let viewController = NavigationController.sharedInstance.storyboardViewControllerFromString(strControllerClass)!
        self.navigationController!.pushViewController(viewController, animated: true)
    }
}

class AddTripViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 在加载视图后进行任何额外的设置。
    }
    
    @IBAction func navigate(_ sender: Any) {
        popOrPushToViewController("ListViewController")
    }
}
英文:

We have Router class to navigate the viewController to another view controller, It's working as expected but when randomly the viewControllersStack gets nil and crash occurred. We tried to use it "if let" to avoid the crash but the issue here is black screen appeared when the viewControllersStack is nil. so we have reverted it back. Can you suggest why the navigation stack is nil if the navigation is nil how to handle it?

private func PopOrPushToViewController(_ strControllerClass: String) {
    
    //get the list of controllers in the stack
    let viewControllersStack: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]
    var boolDidNaviagtion = false
    for viewController in viewControllersStack {
        if boolDidNaviagtion {
            viewController.removeFromParent()
        }
        if String(describing: type(of: viewController)) == strControllerClass {
            boolDidNaviagtion = true
            self.navigationController?.popToViewController(viewController, animated: true)
        }
    }
    if !boolDidNaviagtion {
        let viewController = NavigationController.sharedInstance.storyboardViewControllerFromString(strControllerClass)!
        self.navigationController!.pushViewController(viewController, animated: true)
    }
}



class AddTripViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBAction func navigate(_ sender: Any) {
        popOrPushToViewController( "ListViewController")
    }
    
}

答案1

得分: 0

问题可能出在你的使用方式上:

viewController.removeFromParent()

如果你在堆栈中进行了pop到一个视图控制器,其他视图控制器将自动被移除。

尝试将你的函数更改为这样:

private func PopOrPushToViewController(_ strControllerClass: String) {
    
    // 获取堆栈中的控制器列表
    if let vcStack: [UIViewController] = self.navigationController?.viewControllers {
        
        var didPop = false
        
        for vc in vcStack {
            
            // 如果我们在导航控制器的控制器堆栈中找到了所需的视图控制器,
            // 就弹出到它,将didPop标志设置为true,并停止查找
            if String(describing: type(of: vc)) == strControllerClass {
                self.navigationController?.popToViewController(vc, animated: true)
                didPop = true
                break
            }
            
        }
        
        // 如果我们没有弹出到所需的视图控制器,
        // 实例化它并将它推入堆栈
        if !didPop {
            if let vc = NavigationController.sharedInstance.storyboardViewControllerFromString(strControllerClass) {
                navigationController?.pushViewController(vc, animated: true)
            }
        }
        
    }
    
}
英文:

The problem is likely your use of:

viewController.removeFromParent()

If you pop to a VC in the stack, the other VCs will be removed automatically.

Try changing your func to this:

private func PopOrPushToViewController(_ strControllerClass: String) {
	
	// get the list of controllers in the stack
	if let vcStack: [UIViewController] = self.navigationController?.viewControllers {

		var didPop = false

		for vc in vcStack {

			// if we find the desired VC already in the navVC's stack of controllers,
			// pop to it, set the didPop flag to true, and quit looking
			if String(describing: type(of: vc)) == strControllerClass {
				self.navigationController?.popToViewController(vc, animated: true)
				didPop = true
				break
			}

		}
		
		// if we did NOT pop to the desired VC,
		// instantiate it and push it onto the stack
		if !didPop {
			if let vc = NavigationController.sharedInstance.storyboardViewControllerFromString(strControllerClass) {
				navigationController?.pushViewController(vc, animated: true)
			}
		}

	}
	
}

huangapple
  • 本文由 发表于 2020年1月6日 19:34:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611404.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定