如何从PageViewController访问ViewController组件

我有两个简单的看法如下

在这里输入图像说明

第一个是PageView,第二个是简单的viewController,顶部有一个图像视图

viewController的代码如下

class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.white imgView.image = UIImage(named: "dog0") } } 

当我运行这个视图控制器作为初始视图控制器。 它工作正常。 它正确地显示图像

但是当我从页面视图控制器使用以下代码做同样的事情

 class PageViewController: UIPageViewController, UIPageViewControllerDataSource { let imageNames = ["dog0","dog1","dog2"] override func viewDidLoad() { super.viewDidLoad() self.dataSource = self let eachView = ViewController() eachView.imageName = imageNames.first let viewControllers = [eachView] setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil) } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { return nil } func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { return nil } } 

 class ViewController: UIViewController { var imageName : String? { didSet { imgView.image = UIImage(named: imageName!) } } @IBOutlet weak var imgView: UIImageView! override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.white } } 

我得到以下错误

 fatal error: unexpectedly found nil while unwrapping an Optional value 

在线

 imgView.image = UIImage(named: imageName!) 

什么问题和如何解决这个问题?

问题是这一行:

 let eachView = ViewController() 

这将“无忧无虑”地创build一个ViewController实例,而不需要任何关联的主view 。 因此,当视图加载时,它是空的。 因此,视图中没有图像视图,而imgViewnil 。 因此,当你引用imgView就好像它不是nil (试图设置它的image ),你会崩溃。

正确的过程是实例化您在故事板中devise的ViewController。 那个 ViewController实例在它的view有一个图像视图,因为你devise了它(你把它放在那里),而且它有一个imgViewsockets,就像你已经知道的一样,因为你devise了它(放在那里)。

要获取 ViewController实例,请获取对故事板的引用(可能为self.storyboard ),并调用instantiateViewController(withIdentifier:) 。 当然,你必须在故事板中为这个ViewController实例指定一个标识符。

那么你需要像这样重写ViewController:

 class ViewController: UIViewController { var imageName : String? { didSet { imgView?.image = UIImage(named: imageName!) } } @IBOutlet weak var imgView: UIImageView? // note the question mark override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.white imgView?.image = UIImage(named: imageName!) // note the repeat } } 

原因是你现在有一个计时问题:你正在设置imageName之前的视图加载,所以imgView 仍然没有连接到它的sockets。 通过将关键字行移动到viewDidLoad ,确保我们实际拥有一个视图和一个插口之后执行此操作。