Why do some views appear as a red no entry sign in widgets?
I got this yellow no entry (ghostbusters without the ghost lol) sign after trying to include a chart from the Charts library (subclass of UIView) using a UIViewRepresentable wrapper. I couldn't find the yellow no entry sign documented anywhere and wasn't sure if it originated from the Charts library or iOS itself so it was a relief to see that you saw the same issue and this set me on the right path to coming up with a solution.
From this post that you referenced above, an Apple Engineer says "UIKit views wrapped in UIViewRepresentable will not work in WidgetKit. When the views are encoded from your extension to be displayed they will appear blank.". I don't think that is entirely accurate. I think it will appear yellow with a red "no entry" sign.
https://developer.apple.com/forums/thread/653471?answerId=619627022#619627022
I got around this issue by rendering my chart as a UIImage and displaying the image on the widget instead of the UIView version of the chart. That should suffice for my purposes as I don't need it to be interactive like I do in the app.
Background
Widget Views are static.
They don't support animation, navigation nor user interaction (with the exception of Link
). And they must be written in pure SwiftUI.
List of views that are not allowed in WidgetKit
Note that the list is not exhaustive, provided mostly with examples:
Interactive views (ones you can interact with, e.g., by touching them):
List
Form
ScrollView
TabView
Map
Picker
Slider
- and so on...
Animated views:
ProgressView
Navigation views (you can't use the standard navigation - for this you have
Link
):NavigationView
NavigationLink
UIKit Wrappers for UIKit Views/ViewControllers:
UIViewRepresentable
UIViewControllerRepresentable
Replacements
If you want to use any of the above views, e.g. an interactive view like List
, you need to create it out of non-interactive views - here VStack
+ ForEach
.
Use ForEach inside a VStack:
var body: some View{
ZStack{
self.backgroundColor
VStack{
ForEach(0...1, id: \.self){ entry in
Text("\(entry)")
}
}
}
}