Created
September 6, 2023 15:27
-
-
Save LukasCZ/1e1da01102b22e112b9c34cbb3db16b8 to your computer and use it in GitHub Desktop.
Supporting iOS 17 widget environment variables on previous releases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WidgetEnvironmentBackporting.swift | |
// Widget Extension | |
// | |
// Created by Lukas Petr on 06.09.2023. | |
// Copyright © 2023 Glimsoft. All rights reserved. | |
// | |
// This solution is heavily inspired by https://developer.apple.com/forums/thread/733780?answerId=759064022#759064022 | |
// All credit should go to him. | |
import SwiftUI | |
struct MyWidgetShowsContainerBackgroundKey: EnvironmentKey { | |
static let defaultValue: Bool = true | |
} | |
struct MyWidgetRenderingModeIsVibrant: EnvironmentKey { | |
static let defaultValue: Bool = false | |
} | |
struct MyWidgetContentMargins: EnvironmentKey { | |
static let defaultValue = EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) | |
} | |
struct MyWidgetContentMarginsAreAvailable: EnvironmentKey { | |
static let defaultValue: Bool = false | |
} | |
extension EnvironmentValues { | |
var myWidgetShowsContainerBackground: Bool { | |
set { self[MyWidgetShowsContainerBackgroundKey.self] = newValue } | |
get { self[MyWidgetShowsContainerBackgroundKey.self] } | |
} | |
var myWidgetRenderingModeIsVibrant: Bool { | |
set { self[MyWidgetRenderingModeIsVibrant.self] = newValue } | |
get { self[MyWidgetRenderingModeIsVibrant.self] } | |
} | |
var myWidgetContentMargins: EdgeInsets { | |
set { self[MyWidgetContentMargins.self] = newValue } | |
get { self[MyWidgetContentMargins.self] } | |
} | |
var myWidgetContentMarginsAreAvailable: Bool { | |
set { self[MyWidgetContentMarginsAreAvailable.self] = newValue } | |
get { self[MyWidgetContentMarginsAreAvailable.self] } | |
} | |
} | |
// Magic happens here | |
struct WidgetEnvironmentReader<Content: View>: View { | |
var content: () -> Content | |
init(@ViewBuilder content: @escaping () -> Content) { | |
self.content = content | |
} | |
var body: some View { | |
if #available(iOS 17, *) { | |
WidgetEnvironmentViewBuilder(content: content) | |
} else { | |
content() | |
} | |
} | |
} | |
extension WidgetEnvironmentReader { | |
@available(iOS 17, *) | |
struct WidgetEnvironmentViewBuilder<C: View>: View { | |
@Environment(\.showsWidgetContainerBackground) var showsWidgetContainerBackground | |
@Environment(\.widgetRenderingMode) var widgetRenderingMode | |
@Environment(\.widgetContentMargins) var widgetContentMargins | |
var content: () -> C | |
init(@ViewBuilder content: @escaping () -> C) { | |
self.content = content | |
} | |
var body: some View { | |
content() | |
.environment(\.myWidgetShowsContainerBackground, self.showsWidgetContainerBackground) | |
.environment(\.myWidgetRenderingModeIsVibrant, self.widgetRenderingMode == .vibrant) | |
.environment(\.myWidgetContentMargins, self.widgetContentMargins) | |
.environment(\.myWidgetContentMarginsAreAvailable, true) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use it, you can just wrap your widget entry view in the
WidgetEnvironmentReader
, like this: