NSHostingController 是 macOS(AppKit)中用于承载 SwiftUI 视图的桥接控制器。它的主要作用是:
把 SwiftUI 的 View 嵌入到 AppKit 的 NSViewController 体系中。
类定义
class NSHostingController<Content> : NSViewController where Content : View
它继承自 NSViewController,并且泛型 Content 必须是 SwiftUI 的 View 类型。
构造方法
init(rootView: Content)
Content 是任意 SwiftUI View;
例如:
let controller = NSHostingController(rootView: MySwiftUIView())
它会自动将 SwiftUI 的视图渲染为一个 NSViewController 可用的界面。
主要属性
1、rootView:Content类型,当前显示的 SwiftUI 视图,可以动态替换
2、view:NSView类型,NSViewController 的视图,用于嵌入到 AppKit 界面。
let splitView = NSSplitView()
splitView.isVertical = true
let leftView = NSHostingController(rootView: LefttView()).view // 将 NSViewController 视图转换为 NSView 视图
splitView.addArrangedSubview(leftView)
3、preferredContentSize:CGSize类型,SwiftUI View 的理想大小(可重写)。
生命周期方法
生命周期方法继承自 NSViewController:
1、viewDidLoad():视图加载完成时调用(可重写)。
2、viewWillAppear() / viewDidAppear():视图即将/已经显示。
3、viewWillLayout() / viewDidLayout():视图即将/已经布局。
4、viewWillDisappear() / viewDidDisappear():视图即将/已经消失。
这些方法可以在子类中重写,结合 SwiftUI 与 AppKit 逻辑。
使用场景
1、动态更新rootView
可以随时修改 rootView 来切换 SwiftUI 内容:
let leftView = NSHostingController(rootView: AnyView(LefttView()))
leftView.rootView = AnyView(RightView())
2、在SwiftUI的NSWindow中:
let contentView = NSHostingController(rootView: MySwiftUIView()).view
window.contentView = contentView
3、创建自定义NSHostingController子类,并重写生命周期方法:
class MyHostingController: NSHostingController<MySwiftUIView> {
override func viewDidLoad() {
super.viewDidLoad()
print("SwiftUI视图加载完成")
}
}
4、NSPopover 中使用 SwiftUI 视图:
struct PopoverContentView: View {
var body: some View {
VStack(spacing: 10) {
Text("你好,这是浮窗")
}
}
}
let popover = NSPopover()
popover.contentViewController = NSHostingController(rootView: PopoverContentView())
popover.contentViewController 要求是 NSViewController;
MySwiftUIView() 是 SwiftUI 的 View;
所以必须用 NSHostingController 包装它;
这样就能在 Popover、窗口、Sidebar 等 AppKit 组件中显示 SwiftUI 内容。
关于NSViewController在NSPopover用法,具体请见《macOS浮动窗口NSPopover》的“使用示例”部分。
常见用途
1、弹出框中的内容:popover.contentViewController = NSHostingController(…)。
2、创建窗口的根视图控制器:window.contentViewController = NSHostingController(…)。
3、自定义 NSView 容器内部使用 SwiftUI:将 SwiftUI 嵌入任意 NSView 子视图中。
4、SwiftUI <-> AppKit 混合开发:作为桥梁连接 SwiftUI 和 NSViewController。
UIHostingController 的关系?
1、UIHostingController:用于在iOS / iPadOS / tvOS,使用SwiftUI 嵌入 UIKit。
2、NSHostingController:用于在macOS,使用SwiftUI 嵌入 AppKit。
它们原理相同,只是平台不同。
总结
NSHostingController 是 SwiftUI 视图与 AppKit 系统桥接的关键类。凡是 AppKit 需要 NSViewController 的地方,想用 SwiftUI,就必须使用它。
相关文章
macOS浮动窗口NSPopover:https://fangjunyu.com/2025/06/29/macos%e6%b5%ae%e5%8a%a8%e7%aa%97%e5%8f%a3nspopover/