如何在 `UIPageViewController` 的子视图中引用 `IBOutlet`
How reference `IBOutlet`s in subviews of `UIPageViewController`
我读到,如果您通过初始化程序直接实例化 class (UIViewController),则不会连接 IBOutlets。我的问题是我引用了 nil IBOutlet
,导致崩溃。
我有很多观察者更新 vc1
、vc2
和 vc3
中的视图(UIPageViewController
中的 "pages")。为了保持我的代码干净,我想在 UIPageViewController
class 中添加所有观察者,而不是在 vc1
、vc2
、& [=] 的 viewDidLoad
中17=].
但是,我无法引用 UIPageViewController
中的 IBOutlets
子视图,因为它们为零。有没有人对如何以我可以访问子视图的 IBOutlets
的方式设置 UIPageViewController
有建议?
我在其他应用更新屏幕上不可见的页面视图时遇到了问题(例如:在 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)
}
-
// ViewController1.swift
@IBOutlet weak var scoreBoard: UIView!
func viewDidLoad() {
super.viewDidLoad()
}
func handleEventDataChange() {
if scoreBoard.alpha != 0 { // <-- Crash here
// update scoreboard
}
}
编辑:
除了JRTurton的回答,我还发现我在错误的地方添加了观察者class。
NotificationCenter.default.addObserver(self, selector: #selector(vc1.handleEventDataChange), name: .eventDataChanged, object: nil)
应该是
NotificationCenter.default.addObserver(vc1, selector: #selector(vc1.handleEventDataChange), name: .eventDataChanged, object: nil)
您正在从情节提要中加载您的视图控制器,因此插座将被连接(假设它在情节提要中都已正确连接)。
问题的最可能原因是在视图控制器加载视图之前调用了方法,因此它们还没有机会连接任何东西。
对出口有副作用的外部调用函数可能应该从检查 isViewLoaded
开始,以防止出现此问题。理想情况下,您应该配置模型对象以传递给视图控制器,视图控制器可以立即对其进行操作(如果加载了视图)或用于 viewDidLoad
处的配置
(此外,布局子视图的视图不是添加观察者的好地方 - 可以称为 lot)
我读到,如果您通过初始化程序直接实例化 class (UIViewController),则不会连接 IBOutlets。我的问题是我引用了 nil IBOutlet
,导致崩溃。
我有很多观察者更新 vc1
、vc2
和 vc3
中的视图(UIPageViewController
中的 "pages")。为了保持我的代码干净,我想在 UIPageViewController
class 中添加所有观察者,而不是在 vc1
、vc2
、& [=] 的 viewDidLoad
中17=].
但是,我无法引用 UIPageViewController
中的 IBOutlets
子视图,因为它们为零。有没有人对如何以我可以访问子视图的 IBOutlets
的方式设置 UIPageViewController
有建议?
我在其他应用更新屏幕上不可见的页面视图时遇到了问题(例如:在 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)
}
-
// ViewController1.swift
@IBOutlet weak var scoreBoard: UIView!
func viewDidLoad() {
super.viewDidLoad()
}
func handleEventDataChange() {
if scoreBoard.alpha != 0 { // <-- Crash here
// update scoreboard
}
}
编辑:
除了JRTurton的回答,我还发现我在错误的地方添加了观察者class。
NotificationCenter.default.addObserver(self, selector: #selector(vc1.handleEventDataChange), name: .eventDataChanged, object: nil)
应该是
NotificationCenter.default.addObserver(vc1, selector: #selector(vc1.handleEventDataChange), name: .eventDataChanged, object: nil)
您正在从情节提要中加载您的视图控制器,因此插座将被连接(假设它在情节提要中都已正确连接)。
问题的最可能原因是在视图控制器加载视图之前调用了方法,因此它们还没有机会连接任何东西。
对出口有副作用的外部调用函数可能应该从检查 isViewLoaded
开始,以防止出现此问题。理想情况下,您应该配置模型对象以传递给视图控制器,视图控制器可以立即对其进行操作(如果加载了视图)或用于 viewDidLoad
(此外,布局子视图的视图不是添加观察者的好地方 - 可以称为 lot)