如何在UIPageViewController的子视图中引用IBOutlet

时间:2019-01-08 18:36:46

标签: swift instantiation uipageviewcontroller iboutlet

如果您通过初始化程序直接实例化一个类(UIViewController),则我将无法连接IBOutlets。我的问题是我引用的nil IBOutlet导致崩溃。

我有很多观察者来更新vc1vc2vc3UIPageViewController中的“页面”)中的视图。为了保持代码的整洁,我想将所有观察者添加到UIPageViewController类,而不是viewDidLoadvc1vc2的{​​{1}}类中。

但是,我无法引用vc3中的IBOutlets子视图,因为它们的值为零。有人对我可以访问子视图的UIPageViewController的方式提供有关如何设置UIPageViewController的建议吗?

我在其他应用程序中无法更新屏幕上不可见的页面视图(例如:在屏幕上IBOutlets时在vc3中更新视图)时遇到了麻烦。对于这种目标,vc1是个坏主意吗?我应该只是让用户可以看到的一个大视图吗?

UIPageViewController

-

// UIPageViewController.swift

var vc1: ViewController1 = {
  let storyboard = UIStoryboard(name: "Main", bundle: nil)
  return (storyboard.instantiateViewController(withIdentifier: "ViewController1") as? ViewController1)!
}()

var vc2: ViewController2 = {
  let storyboard = UIStoryboard(name: "Main", bundle: nil)
  return (storyboard.instantiateViewController(withIdentifier: "ViewController2") as? ViewController2)!
}()

var vc3: ViewController3 = {
  let storyboard = UIStoryboard(name: "Main", bundle: nil)
  return (storyboard.instantiateViewController(withIdentifier: "ViewController3") as? ViewController3)!
}()

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
  if viewController == vc2 {
    return vc1
  } else if viewController == vc3 {
    return vc2
  }
  return nil
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
  if viewController == vc1 {
    return vc2
  } else if viewController == vc2 {
    return vc3
  }
  return nil
}

  func viewDidLayoutSubviews() {
    // Adding observer for ViewController1
    NotificationCenter.default.addObserver(self, selector: #selector(vc1.handleEventDataChange), name: .eventDataChanged, object: nil)
  }

编辑:

除了JRTurton的回答,我还发现我在错误的类中添加了观察者。

// ViewController1.swift

@IBOutlet weak var scoreBoard: UIView!

func viewDidLoad() {
  super.viewDidLoad()
}

func handleEventDataChange() {
  if scoreBoard.alpha != 0 { // <-- Crash here
    // update scoreboard
  }
} 

应该是

NotificationCenter.default.addObserver(self, selector: #selector(vc1.handleEventDataChange), name: .eventDataChanged, object: nil)

1 个答案:

答案 0 :(得分:2)

您是从情节提要中加载视图控制器的,因此插座将被连接(假设情节提要中的所有线缆均已正确连接)。

最可能的原因是在视图控制器加载视图之前调用了这些方法,因此它们还没有机会进行任何连接。

可能会对插座产生副作用的外部调用函数应以isViewLoaded开头,以防止出现此问题。理想情况下,您应该配置模型对象以传递给视图控制器,视图控制器可以立即对其执行操作(如果加载了视图),或者可以在viewDidLoad

进行配置

(此外,视图布局子视图并不是添加观察者的好地方-可以称为 lot