WidgetKit Swiftui Widget zeigt Inhalte nicht ordnungsgemäß auf dem Startbildschirm an
Posted: 25 Feb 2025, 11:20
Ich arbeite mit WidgetKit an einem Swiftui -Widget und habe ein Problem gestoßen, bei dem der Inhalt des Widgets auf dem Startbildschirm nicht korrekt angezeigt wird. Der Widget -Inhalt wird als farbige Kästchen angezeigt, anstatt den erwarteten Text und Elemente anzuzeigen. Die Vorschau in Swiftui Canvas funktioniert jedoch vollkommen in Ordnung.
Hier ist mein Code für die Widget -Ansicht:
Widget -Snapshot mit Dummydaten:
Widget im Startbildschirm:
Code: Select all
import WidgetKit
import SwiftUI
import Intents
//MARK: - Creating provider for providing data for widget
struct Provider: TimelineProvider {
typealias Entry = WidgetEntry
///Placeholder to show static data to user
func placeholder(in context: Context) -> WidgetEntry {
WidgetEntry(date: Date(),
topThreeMovies: [dummyMovie, dummyMovie, dummyMovie])
}
///Snapshot to use a preview when adding widgets
func getSnapshot(in context: Context, completion: @escaping (WidgetEntry) -> ()) {
/// Initial snapshot or loading type widget
let entry = WidgetEntry(date: Date(),
topThreeMovies: [dummyMovie, dummyMovie, dummyMovie])
completion(entry)
}
/// This function refreshes the widget for events
func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {
let movieListViewModel = MovieListViewModel()
// Fetch the top three movies using the view model
movieListViewModel.fetchTopThreeMovies { topThreeMovies in
/// Initializing empty array for entries of WidgetEntry
var entries: [WidgetEntry] = []
///Set value for currentDate
let currentDate = Date()
/// Specifying data for entry
let entry = WidgetEntry(date: Date(),
topThreeMovies:topThreeMovies )
/// Refresh widget every 15 minutes
let refreshTime = Calendar.current.date(byAdding: .minute, value: 1, to: currentDate)
entries.append(entry)
/// Creating Timeline
let timeline = Timeline(entries: entries, policy: .after(refreshTime!))
completion(timeline)
}
}
}
// MARK: - Top Movies Widget Entry View
struct TopMoviesWidgetEntryView: View {
var entry: Provider.Entry
/// Access the widget family environment variable
@Environment(\.widgetFamily) var family
@ViewBuilder
var body: some View {
/// Switch based on the widget family
switch family {
case .systemMedium:
/// Display the MovieWidgetView for the medium widget size
MovieWidgetView(topThreeMovies: [dummyMovie, dummyMovie, dummyMovie])
default:
/// Handle other widget family types (fatalError is used here for simplicity)
fatalError("Unsupported widget family")
}
}
}
// MARK: - Widget Configuration
struct TopMoviesWidget: Widget {
/// Unique identifier for the widget
let kind: String = "TopMoviesWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
TopMoviesWidgetEntryView(entry: entry)
}
.configurationDisplayName("Top Movies Widget")
.description("This is a widget of Today's Top Movies.")
.supportedFamilies([.systemMedium])
}
}
// MARK: - Create a preview for the widget entry view
struct TopMoviesWidget_Previews: PreviewProvider {
static var previews: some View {
TopMoviesWidgetEntryView(entry: WidgetEntry(date: Date(),
topThreeMovies: [dummyMovie, dummyMovie, dummyMovie]))
.previewContext(WidgetPreviewContext(family: .systemMedium))
}
}
Code: Select all
import SwiftUI
import WidgetKit
/// Top Movies Widget View
struct MovieWidgetView: View {
// @StateObject var viewModel = MovieListViewModel()
var topThreeMovies: [Movie]
var body: some View {
HStack(alignment: .top) {
/// Show Week Day, Date and List Button
VStack(alignment: .leading) {
///Week Day
Text("\(Date().getFormattedWeekDay())")
.foregroundColor(.orange)
.bold()
///Date
Text("\(Date().getFormattedDate())")
.bold()
Spacer()
///List Button to navigate to Movie List screen
Button(action: {
/// Close the widget view and navigate to MovieListView
}) {
Label("", systemImage: "list.bullet.circle.fill").body
.foregroundColor(.orange)
.font(.system(size: 30))
}
}
.padding(EdgeInsets(top: 20, leading: 0, bottom: 0, trailing: 10))
Spacer()
///Top Three movies Listr
VStack(alignment: .leading) {
ForEach(0.. Void) {
isLoading = true
///get top three movies from all movies
for i in 0.. Int? {
return movies.firstIndex { $0.id == movie.id }
}
Widget im Startbildschirm: