在同一容器视图中从一个视图控制器切换到另一个视图

时间:2017-08-03 07:16:20

标签: ios swift uiviewcontroller

我有两个视图控制器:ViewControllerAViewControllerBViewControllerA被添加到容器视图中,并且具有按钮。点击按钮,ViewControllerB应替换ViewControllerA。我怎样才能做到这一点?问题是按钮位于ViewControllerB内,而不是主视图控制器。

主要ViewController

class ViewController: UIViewController {

    @IBOutlet weak var containerView: UIView!
    weak var currentViewController: UIViewController?

    override func viewDidLoad() {
        self.currentViewController = self.storyboard?.instantiateViewController(withIdentifier: "Verify")
        self.currentViewController!.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChildViewController(self.currentViewController!)
        self.initializeFirstScreen(subView: self.currentViewController!.view, toView: self.containerView)

        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    func initializeFirstScreen(subView:UIView, toView parentView:UIView){

        parentView.addSubview(subView)

        var viewBindingDict = [String: AnyObject]()
        viewBindingDict["subView"] = subView
        parentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[subView]|", options: [], metrics: nil, views: viewBindingDict))
        parentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[subView]|", options: [], metrics: nil, views: viewBindingDict))
    }

    func switchToValidate(){

        let newViewController = self.storyboard?.instantiateViewController(withIdentifier: "Validate")

        //this line throws error
        //fatal error: unexpectedly found nil while unwrapping an Optional value
        newViewController!.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChildViewController(newViewController!)
        initializeFirstScreen(subView: (newViewController?.view)!, toView: self.containerView)

    }
}

ViewControllerA

class VerifyViewController: UIViewController {

    let mainViewController = ViewController()    

    @IBAction func VerifyNumber(){

        self.switchScreens()

    }


    func switchScreens(){

        mainViewController.switchToValidate()

    }
}

switchToValidate会抛出以下错误:

  

致命错误:在解包可选值时意外发现nil

1 个答案:

答案 0 :(得分:1)

我在理解你的代码时苦苦挣扎。

如果要求将按钮保持在ViewControllerA内,则应在其中注入主视图控制器的引用。在ViewControllerA中,您正在创建ViewController的新实例。

所以,在ViewController内,而不是(你在这里创建一个全新的控制器):

let viewController = ViewController()

你需要这样的东西:

weak var mainViewController: ViewController?

viewDidLoad中,您可以在ViewControllerA内注入该属性,例如:

if let viewControllerA = 
    self.storyboard?.instantiateViewController(withIdentifier: "Validate") as? ViewControllerA {
    viewControllerA.mainViewController = self
    // other code here
}

现在,在ViewControllerA中,你有一个对主控制器的引用,你可以切换到另一个控制器。

很少注意到:

    在覆盖super.viewDidLoad() 时,应将
  • viewDidLoad作为第一个指示
  • 更喜欢if let(或guard)语法到!以处理选项。显然除非有必要。