如何从 App Delegate 访问视图控制器 (XCode 9)
How to I access View Controllers from App Delegate (XCode 9)
我有一个带有拆分视图的故事板。当应用程序启动时,我想为视图设置模型。
我有一个简单的class天:
import Foundation
class Day: NSObject{
var date: Date
var sleep: Double
init(date: Date, sleep: Double){
self.date = date
self.sleep = sleep
super.init()
}
override convenience init(){
self.init(date: Date(), sleep: 8.0)
}
}
我有一个拆分窗格的视图控制器:
import Cocoa
class DayViewController: NSViewController {
private var day: Day = Day()
@IBOutlet weak var sleep: NSTextField!
func set(day: Day){
self.day = day
//update()
}
// func update(){
//sleep.doubleValue = day.sleep
// }
}
我想在应用程序委托中设置日,以便显示它。
如何在 AppDelegate 中获取 DayViewController 的实例以便我可以设置该值?
你试过这个吗?
if window?.rootViewController is DayViewController {
guard let dayVC = window?.rootViewController as? DayViewController else {
//there was an error
return
dayVC.set(day: new Day())
}
我不确定它是否有效。也许最好按照@Siyavash 所说的方式进行...放入 viewDidLoad 本身。
这就是我最终所做的。认为它可能很有趣。仍然不确定这是否是黑客攻击。
在 DayViewController 中,我在 AppDelegate 中设置了对它的引用:
override func viewDidLoad() {
super.viewDidLoad()
let app: AppDelegate = NSApplication.shared.delegate as! AppDelegate
app.dayViewController = self
}
然后我可以在 AppDelegate 中设置视图的日期:
var dayViewController: DayViewController?
func applicationDidFinishLaunching(_ aNotification: Notification) {
let day: Day = Day.init(date: Date(), sleep: 9.5)
dayViewController!.set(day: day)
}
根据评论中的要求,这是我现在所做的,我对 swift 有了更多的经验。
该示例使用了一个简单的“Day”class 作为我的模型,但在我的实现中该模型被称为“TrainingDiary”。现在,我的 AppDelegate 中几乎没有任何内容。相反,我做了以下事情:
我有所有提供模型视图的视图控制器实现的协议
protocol TrainingDiaryViewController{
func set(trainingDiary td: TrainingDiary)
}
我有主 window 的视图控制器,它现在有一个 TabViewController(而不是我的拆分视图,但这种方法适用于此)。
在那个视图控制器中我重写了 prepare(for:sender:):
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let tabViewController = segue.destinationController as? NSTabViewController else {return}
for controller in tabViewController.childViewControllers{
if let c = controller as? TrainingDiaryViewController{
trainingDiaryVCs.append(c)
}
}
}
这意味着我现在可以引用作为 TrainingDiary 视图的所有视图控制器
在主视图中有一个 TableView,我用它来管理培训日记(即添加、删除、select)。主视图控制器设置为 TableViews 委托,TableView 在 IB 中设置为具有单个 selection 并避免没有 selection。然后我实施了:
func tableViewSelectionDidChange(_ notification: Notification) {
if let trainingDiary = trainingDiarysArrayController.selectedObjects[0] as? TrainingDiary{
for c in trainingDiaryVCs{
c.set(trainingDiary: trainingDiary)
}
}
}
一切都很好。
我有一个带有拆分视图的故事板。当应用程序启动时,我想为视图设置模型。
我有一个简单的class天:
import Foundation
class Day: NSObject{
var date: Date
var sleep: Double
init(date: Date, sleep: Double){
self.date = date
self.sleep = sleep
super.init()
}
override convenience init(){
self.init(date: Date(), sleep: 8.0)
}
}
我有一个拆分窗格的视图控制器:
import Cocoa
class DayViewController: NSViewController {
private var day: Day = Day()
@IBOutlet weak var sleep: NSTextField!
func set(day: Day){
self.day = day
//update()
}
// func update(){
//sleep.doubleValue = day.sleep
// }
}
我想在应用程序委托中设置日,以便显示它。
如何在 AppDelegate 中获取 DayViewController 的实例以便我可以设置该值?
你试过这个吗?
if window?.rootViewController is DayViewController {
guard let dayVC = window?.rootViewController as? DayViewController else {
//there was an error
return
dayVC.set(day: new Day())
}
我不确定它是否有效。也许最好按照@Siyavash 所说的方式进行...放入 viewDidLoad 本身。
这就是我最终所做的。认为它可能很有趣。仍然不确定这是否是黑客攻击。
在 DayViewController 中,我在 AppDelegate 中设置了对它的引用:
override func viewDidLoad() {
super.viewDidLoad()
let app: AppDelegate = NSApplication.shared.delegate as! AppDelegate
app.dayViewController = self
}
然后我可以在 AppDelegate 中设置视图的日期:
var dayViewController: DayViewController?
func applicationDidFinishLaunching(_ aNotification: Notification) {
let day: Day = Day.init(date: Date(), sleep: 9.5)
dayViewController!.set(day: day)
}
根据评论中的要求,这是我现在所做的,我对 swift 有了更多的经验。
该示例使用了一个简单的“Day”class 作为我的模型,但在我的实现中该模型被称为“TrainingDiary”。现在,我的 AppDelegate 中几乎没有任何内容。相反,我做了以下事情:
我有所有提供模型视图的视图控制器实现的协议
protocol TrainingDiaryViewController{ func set(trainingDiary td: TrainingDiary) }
我有主 window 的视图控制器,它现在有一个 TabViewController(而不是我的拆分视图,但这种方法适用于此)。
在那个视图控制器中我重写了 prepare(for:sender:):
override func prepare(for segue: NSStoryboardSegue, sender: Any?) { super.prepare(for: segue, sender: sender) guard let tabViewController = segue.destinationController as? NSTabViewController else {return} for controller in tabViewController.childViewControllers{ if let c = controller as? TrainingDiaryViewController{ trainingDiaryVCs.append(c) } } }
这意味着我现在可以引用作为 TrainingDiary 视图的所有视图控制器
在主视图中有一个 TableView,我用它来管理培训日记(即添加、删除、select)。主视图控制器设置为 TableViews 委托,TableView 在 IB 中设置为具有单个 selection 并避免没有 selection。然后我实施了:
func tableViewSelectionDidChange(_ notification: Notification) { if let trainingDiary = trainingDiarysArrayController.selectedObjects[0] as? TrainingDiary{ for c in trainingDiaryVCs{ c.set(trainingDiary: trainingDiary) } } }
一切都很好。