swift - 如何在 `UIPageViewController` 的子视图中引用`IBOutlet`
问题描述
我读到如果您通过初始化程序直接实例化一个类(UIViewController),则不会连接 IBOutlets。我的问题是我引用了 nil IBOutlet
,导致崩溃。
我有很多观察者会更新vc1
、vc2
和vc3
(中的“页面” UIPageViewController
)中的视图。为了保持我的代码干净,我想在UIPageViewController
类中添加所有观察者,而不是在viewDidLoad
of vc1
, vc2
, &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)
}
-
// ViewController1.swift
@IBOutlet weak var scoreBoard: UIView!
func viewDidLoad() {
super.viewDidLoad()
}
func handleEventDataChange() {
if scoreBoard.alpha != 0 { // <-- Crash here
// update scoreboard
}
}
编辑:
除了 JRTurton 的回答,我还发现我在错误的类中添加了观察者。
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
(另外,视图没有布局子视图不是添加观察者的好地方 - 这可以被称为很多)
推荐阅读
- python - Python如何使日期时间更新时间
- discord - VPS 上的 Discord.js Reactionroles 不起作用
- java - 提供了错误类型的 id - Spring
- javascript - 如何在没有触发器的情况下在 JavaScript 中每秒播放声音
- javascript - 我在这里调用哪个 createReadStream?
- r - 当使用 gseGO 函数在 R 中选择所有基因时未定义 GSEA 统计
- bash - 我们可以将多个 .gz 文件压缩到 gz 文件上吗
- flutter - 无法访问 Futurebuilder 中的 Snapshot.data
- vue.js - Vuejs 获取动态表单值
- ruby-on-rails - 日志说“fe_sendauth:没有提供密码”,但 rails 控制台工作没有问题