在Swift 3中以编程方式创建一个没有XIB的NSViewController
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Swift 3中以编程方式创建一个没有XIB的NSViewController相关的知识,希望对你有一定的参考价值。
我正在尝试在不使用Interface Builder的情况下制作macOS应用程序。我的项目构建和运行,但我的主视图控制器似乎没有加载其视图。也就是说,不调用viewDidLoad()
方法。我正在使用Xcode-beta 8.0 beta 6(8S201h)。
NSViewController
的Swift 3文档说明了view
属性:
如果在访问它时尚未设置此属性的值,则视图控制器将调用
loadView()
方法。反过来,该方法从视图控制器的nibName
和nibBundle
属性标识的nib文件中设置视图。如果要直接设置视图控制器的视图,请在创建视图控制器后立即设置此属性的值。
而对于viewDidLoad
:
对于以编程方式创建的视图控制器,在
loadView()
方法完成后立即调用此方法。
最后,对于isViewLoaded
:
视图控制器使用其视图的延迟加载:在视图控制器加载到内存后,其
isViewLoaded
属性的值立即为false
。在true
方法返回之后且在系统调用loadView()
方法之前,值会更改为viewDidLoad()
。
所以文档让我相信它是可能的。
我的项目看起来像这样:
.
├── main.swift
└── Classes
├── AppDelegate.swift
└── Controllers
└── PrimaryController.swift
main.swift
import Cocoa
let delegate = AppDelegate()
NSApplication.shared().delegate = delegate
NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
AppDelegate.swift
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let pc = PrimaryController(nibName: nil, bundle: nil)!
print(pc.isViewLoaded)
pc.view = NSView()
print(pc.isViewLoaded)
}
}
PrimaryController.swift
import Cocoa
class PrimaryController: NSViewController {
override func loadView() {
print("PrimaryController.loadView")
}
override func viewDidLoad() {
super.viewDidLoad()
print("PrimaryController.viewDidLoad")
}
}
使用上述方法构建和运行项目会产生此控制台输出:
false
true
也就是说,视图加载了控制器,但是从不调用loadView
和viewDidLoad
方法。
我错过了什么?
仔细阅读文档是有启发性的。特别:
如果在访问它时尚未设置此属性的值,则视图控制器将调用
loadView()
方法。
意思是,只有在属性具有值之前尝试读取loadView()
属性时才会调用view
。直接为属性赋值将绕过方法调用。
所以如果AppDelegate.applicationDidFinishLaunching(_:)
写成这样:
let pc = PrimaryController(nibName: nil, bundle: nil)!
print(pc.isViewLoaded)
let x = pc.view // accessing the view property before it has a value
print(pc.isViewLoaded)
...然后系统将调用loadView
来尝试加载视图:
false
PrimaryController.loadView
false
请注意,viewDidLoad()
仍未被调用,因为没有视图可以自动与控制器关联(即,nib是nil
并且PrimaryController.xib
不存在)。完成该过程的正确方法是在PrimaryController.loadView()
中手动加载视图:
print("PrimaryController.loadView")
view = NSView() // instantiate and bind a view to the controller
现在该程序提供了所需的结果:
false
PrimaryController.loadView
PrimaryController.viewDidLoad
true
从代码生成ViewController的最小设置(Swift 4.1)
class WelcomeViewController: NSViewController {
private lazy var contentView = MyCustomClassOrJustNSView()
override func loadView() {
view = contentView
}
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError()
}
}
以上是关于在Swift 3中以编程方式创建一个没有XIB的NSViewController的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中以编程方式从 MainViewController 切换到 .xib 视图?
尝试在 Swift 中以编程方式设置 rightBarButton