You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI Widget真机/模拟器显示空白,Canvas正常问题求助

SwiftUI Widget Shows in Canvas but Blank on Simulator/Device

Hey there! Let's figure out why your widget works perfectly in the SwiftUI Canvas but goes blank when deployed to a simulator or real device. From looking at your code and the update you shared, here are the key issues to fix:

1. Custom Font Loading Problems

You're using custom fonts like HoeflerText-Italic and Copperplate in your widget. The SwiftUI Canvas often falls back to system fonts if the custom ones aren't properly set up, but devices won't do that. If the fonts aren't added correctly to your project, the Text views that use them won't render—this can cause the entire widget layout to collapse into a blank state.

Fix Steps:

  • Make sure your font files (e.g., .ttf or .otf) are added to your Xcode project, and check the box for your widget target in the "Add to targets" section when importing.
  • Open your project's Info.plist, add the key Fonts provided by application, and list each font file name as a string entry (include the full file name like HoeflerText-Italic.ttf).
  • Verify the fonts are included in your widget target's Build Phases > Copy Bundle Resources.

2. Layout Overflow & Missing Text Constraints

The VStack you removed contains text with large font sizes (44pt and 26pt) plus padding. Widgets have very limited screen space, especially for the .systemMedium size. If the content exceeds the available bounds, SwiftUI might hide the entire view instead of clipping it.

Fix Steps:

Add text scaling and line limits to prevent overflow:

  • Use .minimumScaleFactor(_:) to let text shrink if needed.
  • Use .lineLimit(1) to keep text on a single line.

3. Dangerous Force Unwrapping

Your code uses force unwrapping (!) for getDayOfWeekInString(date:). If this method returns nil (e.g., due to a date parsing error on the device), the view will crash silently—resulting in a blank widget. Always use optional bindings or default values instead.

Corrected WidgetEntryView Code

Here's your updated view with all these fixes applied:

struct WidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        HStack() {
            VStack {
                Spacer()
                VStack(alignment: .leading) {
                    // Replace force unwrap with default value
                    Text(DateManager().getDayOfWeekInString(date: entry.date) ?? "")
                        // Fallback to system font if custom one fails
                        .font(Font(UIFont(name: "HoeflerText-Italic", size: 44) ?? .systemFont(ofSize: 44, weight: .italic)))
                        .foregroundColor(.white)
                        .multilineTextAlignment(.trailing)
                        // Allow text to shrink to fit
                        .minimumScaleFactor(0.5)
                        .lineLimit(1)
                    
                    Text("\(DateManager().getDayAsString(date: entry.date)) \(DateManager().monthAsString(date: entry.date))")
                        .font(Font(UIFont(name: "Copperplate", size: 26) ?? .systemFont(ofSize: 26)))
                        .multilineTextAlignment(.trailing)
                        .foregroundColor(.gray)
                        .minimumScaleFactor(0.6)
                        .lineLimit(1)
                }
            }
            .padding(.leading, 20)
            .padding(.bottom, 20)
            
            Spacer()
            
            VStack(alignment: .trailing, spacing: -20) {
                Text(DateManager().getHour(date: entry.date))
                    .font(Font(UIFont(name: "Copperplate-Bold", size: 86) ?? .systemFont(ofSize: 86, weight: .bold)))
                    .foregroundColor(.white)
                    .multilineTextAlignment(.trailing)
                    .minimumScaleFactor(0.4)
                    .lineLimit(1)
                
                Text(DateManager().getMinuteWithTwoDigits(date: entry.date))
                    .font(Font(UIFont(name: "Copperplate-Bold", size: 86) ?? .systemFont(ofSize: 86, weight: .bold)))
                    .multilineTextAlignment(.trailing)
                    .foregroundColor(.gray)
                    .minimumScaleFactor(0.4)
                    .lineLimit(1)
            }
            .padding(.trailing, 15)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Image(uiImage: #imageLiteral(resourceName: "moon")), alignment: .center)
        // Add a fallback background color to debug layout issues
        .background(Color.black)
    }
}

Additional Debug Tips

  • Add previews for all widget sizes to catch layout issues early:
    struct Widget_Previews: PreviewProvider {
        static var previews: some View {
            Group {
                WidgetEntryView(entry: SimpleEntry(date: Date()))
                    .previewContext(WidgetPreviewContext(family: .systemSmall))
                WidgetEntryView(entry: SimpleEntry(date: Date()))
                    .previewContext(WidgetPreviewContext(family: .systemMedium))
                WidgetEntryView(entry: SimpleEntry(date: Date()))
                    .previewContext(WidgetPreviewContext(family: .systemLarge))
            }
        }
    }
    
  • Use Xcode's Debug View Hierarchy (button in the debug bar) on the simulator/device to inspect the widget's view tree—you'll be able to see if views are hidden, out of bounds, or missing entirely.
  • Double-check your DateManager methods to ensure they handle time zones correctly and never return nil (add guard clauses or default values inside those methods).

内容的提问来源于stack exchange,提问作者Bernard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:20:50