扩展视图时 SwiftUI 预览崩溃

Posted

技术标签:

【中文标题】扩展视图时 SwiftUI 预览崩溃【英文标题】:SwiftUI preview crashes when extending View 【发布时间】:2020-06-10 21:30:11 【问题描述】:

我有一个项目需要支持旧版本的 ios,我正在尝试使用 SwiftUI 来创建仅在用户使用 iOS 13 或更高版本时才会出现的视图。 Xcode 中的 SwiftUI Preview 工作得很好,但是当我扩展 SwiftUI 结构(例如 View)时,该项目将在设备上编译和运行,但 Preview Canvas 崩溃,说明它Failed to build myView.swift。当我点击“诊断”按钮时,它告诉我'View' is only available in iOS 13.0 or neweradd @available attribute to enclosing extension。但是,有问题的扩展名前面已经有@available(iOS 13.0, *)。例如:

@available(iOS 13.0, *)
extension View 
    func myFunc() 

    

为了找到这个问题的根源,我注意到如果预览完全为空,它不会崩溃。只有向其中添加函数或静态属性后,画布才会崩溃。我还尝试在扩展中的每个函数之前添加@available 行,重新启动我的计算机,并删除 DerivedData 文件夹,但似乎没有什么不同。

【问题讨论】:

【参考方案1】:

您不需要@available(iOS 13.0, *),您的应用将无法在低于版本13.0 的任何设备上运行,因此基本上错误表明这是多余的。删除它应该可以解决您的问题。

但是,如果您正在执行 SwiftUI 弱链接并且存在此问题,那么这是 xCode 的一个已知错误。如果没有弱链接,请删除@available(iOS 13.0, *)

编辑:您的链接似乎很弱。

    确保在Build Phases -> Link Binary With Libraries 中将SwiftUI.framework 设置为optional

    确保您的 @available(iOS 13.0, *) 在您的 body 之上,而不是在您的扩展之上

示例:

struct TestView2: View 
    @available(iOS 13.0, *)
    var body: some View 
        Text("test")
    


extension TestView2 
    func abc() 

    


struct TestView2_Previews: PreviewProvider 
    @available(iOS 13.0, *)
    static var previews: some View 
        TestView2()
    

【讨论】:

该应用程序针对的是旧版本的 iOS,但相关视图仅在用户运行 13.0 或更高版本时才会出现。如果没有 @available(iOS 13.0, *) ,应用程序根本无法编译。 知道了,我编辑了我的答案以反映。请检查一下。 我正在使用弱链接,并在我的身体顶部添加了@available(iOS 13.0, *)(而不是在结构上方),但它仍然不起作用。正如你所提到的,这似乎是一个 Xcode 错误,所以我只能希望它尽快得到修复。 上面的代码对我来说很好,我可以预览并且我的目标是 iOS 12.4。无论如何,如果还有什么我可以帮助你的,请告诉我。 问题可能是我正在尝试扩展 SwiftUI 的内置 View 结构,而您的代码正在扩展 TestView2【参考方案2】:

讨论

以下代码示例非常适合我。请注意@available(iOS 13.0, *) 声明属性不仅 View 扩展,而且 用于:

    ContentView 结构,符合View 协议,

    ContentView_Previews 结构,符合PreviewProvider 协议。

仅供参考:我将 Xcode 项目的部署目标设置为 iOS 12.4 以进行测试。

代码示例

import SwiftUI

@available(iOS 13.0, *)
extension View 
    func overlayText<Content>(_ content: Content) -> some View where Content : StringProtocol 
        overlay(Text(content))
    


@available(iOS 13.0, *)
struct ContentView: View 
    static private var initialGreeting = "Hello World!"
    static private var greetings: [String] 
        [
            initialGreeting,
            "Hey Everyone!",
            "Hi Everybody!",
            "Hello Friends!"
            
        ]
    
    @State private var greeting = initialGreeting
    
    var body: some View 
        Button(action:  [greeting] in
            while self.greeting == greeting 
                self.greeting = Self.greetings.randomElement()!
            
        ) 
            Color.green
                .overlayText(greeting)
                .cornerRadius(30)
                .padding(5)
        
        .background(Color.black)
        .frame(height: 50)
        .foregroundColor(.white)
        .font(.system(size: 28, weight: .bold))
        .cornerRadius(30)
        .padding()
    


@available(iOS 13.0, *)
struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

【讨论】:

以上是关于扩展视图时 SwiftUI 预览崩溃的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI Xcode项目新增单元测试(Unit Test)后预览(Preview)崩溃的解决

Xcode如何在预览(Preview)调试中避免与SwiftUI正常运行时环境不一致导致的崩溃

Xcode如何在预览(Preview)调试中避免与SwiftUI正常运行时环境不一致导致的崩溃

Xcode 预览在 DB 循环读取 SwiftUI 时崩溃

Xcode 12.2+生成SwiftUI 2.0 CoreData模板预览时崩溃问题的解决

Xcode 12.2+生成SwiftUI 2.0 CoreData模板预览时崩溃问题的解决