如何从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
。 因此,当视图加载时,它是空的。 因此,视图中没有图像视图,而imgView
是nil
。 因此,当你引用imgView
就好像它不是nil
(试图设置它的image
),你会崩溃。
正确的过程是实例化您在故事板中devise的ViewController。 那个 ViewController实例在它的view
有一个图像视图,因为你devise了它(你把它放在那里),而且它有一个imgView
sockets,就像你已经知道的一样,因为你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
,确保在我们实际拥有一个视图和一个插口之后执行此操作。