如何从PageViewController访问ViewController组件

时间:2017-01-13 02:03:56

标签: ios swift

我有2个简单的视图,如下所示

enter image description here

第一个是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!)

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

1 个答案:

答案 0 :(得分:1)

问题在于这一行:

let eachView = ViewController()

这创建了一个ViewController实例"凭空而来#34;没有任何关联的主view。因此,当视图加载时,它是空的。因此,视图中没有图片视图,imgViewnil。因此,当您引用imgView时,如果它不是nil(尝试设置其image),则会崩溃。

正确的过程是在Storyboard 中实例化您设计的的ViewController。 那个 ViewController实例在view中有一个图片视图,因为你设计了它(你把它放在那里),它有一个imgView插座,如你所知,再次因为你设计了它(你把它放在那里)。

要获取 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 仍未连接到它出口。通过将关键线移动到viewDidLoad,您可以确保我们在实际拥有视图和插座之后执行此操作。