'SwiftUI preview crashes when extending View
I have a project that needs to support an old version of iOS and I'm trying to use SwiftUI for a view that will only appear when the user is on iOS 13 or later. The SwiftUI Preview in Xcode works just fine, but when I extend a SwiftUI struct (such as View), the project will compile and run on a device, but the Preview Canvas crashes, stating that it Failed to build myView.swift. When I click on the "diagnostics" button, it tells me that 'View' is only available in iOS 13.0 or newer and add @available attribute to enclosing extension. However, the extension in question already has @available(iOS 13.0, *) before it. For example:
@available(iOS 13.0, *)
extension View {
func myFunc() {
}
}
In an effort to find the root of this problem, I noticed that the preview won't crash if it's completely empty. Only once I add a function or static property to it will the canvas crash. I have also tried adding the @available line before each function in the extension, rebooting my computer, and deleting the DerivedData folder, but it doesn't seem to have made a difference.
Solution 1:[1]
Discussion
The following code example works well for me. Please note the @available(iOS 13.0, *) declaration attributes for not only the View extension, but also for:
- The
ContentViewstruct, which conforms to theViewprotocol,
and
- The
ContentView_Previewsstruct, which conforms to thePreviewProviderprotocol.
FYI: I set my Xcode Project's deployment target to iOS 12.4 for my test.
Code Example
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()
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jeremy Pearson |
