onmyway133 / blog

🍁 What you don't know is what you haven't learned
https://onmyway133.com/
MIT License
669 stars 33 forks source link

How to update widget for iOS 17 #948

Open onmyway133 opened 9 months ago

onmyway133 commented 9 months ago

iOS 17 has a new Stand by mode so SwiftUI introduces containerBackground for the system to decide when to draw background. It also automatically applies margin to widget so we may need to disable that

To update existing widgets, we can write some useful extension

extension View {
    @ViewBuilder
    func safeContainerBackground(@ViewBuilder content: () -> some View) -> some View {
        if #available(iOS 17.0, *) {
            self.containerBackground(for: .widget, content: content)
        } else {
            self.background(content())
        }
    }
}

extension WidgetConfiguration {
    func safeContentMarginsDisabled() -> some WidgetConfiguration {
        if #available(iOS 15.0, *) {
            return contentMarginsDisabled()
        } else {
            return self
        }
    }
}

So in our Widget configuration, we can use

struct BalanceWidget: Widget {
    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: kind,
            intent: SelectAccountIntent.self,
            provider: BalanceTimelineProvider()
        ) { entry in
            BalanceWidgetView(entry: entry)
        }
        .safeContentMarginsDisabled()
    }
}

struct BalanceWidgetView: View {
    var body: some View {
        ZStack {
            ...
        }
        .safeContainerBackground {
            Color.green
        }
    }
}