Xcode 14 iOS 16中UIViewControllerRepresentable预览崩溃问题
问题场景
在Xcode 14 beta、iOS 16环境下,不使用Storyboard、纯代码实现自定义UIViewController时,接入Xcode Previews会弹出预览错误、直接崩溃,复现代码如下:
import Foundation import UIKit import SwiftUI final class ViewController2: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.green } } struct ViewController2_Previews: PreviewProvider { static var previews: some View { ViewController2() } } extension ViewController2: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> ViewController2 { ViewController2() } func updateUIViewController(_ uiViewController: ViewController2, context: Context) { } }
崩溃根本原因
- 违反
UIViewControllerRepresentable的设计约束:该协议属于SwiftUI视图体系,仅支持被SwiftUI值类型(结构体)遵守。代码中直接让引用类型的UIViewController子类本身遵守该协议,会导致SwiftUI预览引擎做类型解析时出现类型混淆,无法正确识别渲染对象。 PreviewProvider的previews属性要求返回合法的SwiftUI视图(some View),代码中直接返回ViewController2()这个UIKit控制器实例,不属于SwiftUI可识别的渲染类型,预览进程无法完成渲染直接触发崩溃。
修复方案
不要让UIViewController本身遵守UIViewControllerRepresentable,单独创建一个专用的SwiftUI包装结构体承载控制器的适配逻辑,修改后可正常运行的代码如下:
import Foundation import UIKit import SwiftUI final class ViewController2: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.green } } // 单独创建结构体做UIViewController与SwiftUI的适配 struct ViewController2Wrapper: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> ViewController2 { ViewController2() } func updateUIViewController(_ uiViewController: ViewController2, context: Context) { // 可在此处根据SwiftUI层的状态更新控制器属性 } } struct ViewController2_Previews: PreviewProvider { static var previews: some View { // 预览时返回包装后的适配结构体,而非直接返回控制器实例 ViewController2Wrapper() } }
补充:如果需要自定义预览效果,可以直接在包装实例后拼接SwiftUI标准预览修饰符,比如
.preferredColorScheme(.dark)指定深色模式、.previewDevice(PreviewDevice(rawValue: "iPhone 14"))指定预览设备即可。
内容的提问来源于stack exchange,提问作者Mary Doe
相关产品推荐
相关产品推荐

