【问题标题】:SwiftUI preview crashes when extending View扩展视图时 SwiftUI 预览崩溃
【发布时间】: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 文件夹,但似乎没有什么不同。

【问题讨论】:

    标签: ios swift xcode swiftui


    【解决方案1】:

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

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

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

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

    2. 确保您的 @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 扩展,而且 用于:

    1. ContentView 结构,符合View 协议,

    1. 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()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-18
      • 2022-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多