如何在WatchKit Storyboard的WKInterfaceController中嵌入SwiftUI子视图
实现方案
你不需要把WKHostingController作为独立页面控制器使用,通过子控制器内嵌+容器Group承载的方式,就能实现SwiftUI视图和Storyboard布局元素的混合排布,全程不需要改动你现有的SliderView代码,具体步骤如下:
步骤1:Storyboard端配置
打开你对应WKInterfaceController的Storyboard界面,在你想要放置SwiftUI滑块的位置,拖入一个WKInterfaceGroup控件:
- 调整这个Group的位置、宽高,和周围其他Storyboard元素(标签、按钮等)排好布局
- 给这个Group创建IBOutlet连线到你的
WKInterfaceController子类,命名比如sliderContainer - 建议把Group的宽高适配模式设置为和内容匹配,避免布局裁剪
步骤2:控制器代码内嵌HostingController
在你的WKInterfaceController子类中,添加内嵌子控制器的逻辑,注意要强引用WKHostingController实例避免提前释放,示例代码如下:
import WatchKit import SwiftUI class MainInterfaceController: WKInterfaceController { // Storyboard连线的SwiftUI视图容器 @IBOutlet weak var sliderContainer: WKInterfaceGroup! // 强引用HostingController,防止实例被回收 private var sliderHostingController: WKHostingController<SliderView>? override func awake(withContext context: Any?) { super.awake(withContext: context) // 初始化承载SwiftUI视图的控制器 let hostingVC = WKHostingController(rootView: SliderView()) sliderHostingController = hostingVC // 完成内嵌逻辑,将SwiftUI视图挂载到指定容器Group addChild(hostingVC) sliderContainer.setViewController(hostingVC) hostingVC.didMove(toParent: self) } }
注意事项
- 这个方案兼容watchOS 6.0及以上系统版本,覆盖绝大多数现役Apple Watch设备
- 如果需要在
WKInterfaceController和SliderView之间双向传值,只需要给SliderView添加对应的@Binding属性,初始化HostingController时传入绑定即可,和普通SwiftUI视图传值逻辑一致 - 不要用弱引用持有
WKHostingController实例,否则会导致SwiftUI视图意外消失、交互失效
内容的提问来源于stack exchange,提问作者Codetard
相关产品推荐
相关产品推荐

