VariableBlurView
VariableBlurView copied to clipboard
Unusual behavior when used in iOS 17 beta 1
In iOS 17 beta 1, it seems like VariableBlurView displays correctly the first time it's loaded in dark mode, but in the below scenarios, it seems to turn dark:
- Switching to light mode and back to dark mode
- Switching to another app and back when in dark mode I've attached a screen recording in the simulator showing the issue in the first scenario. It happens on physical devices too.
https://github.com/aheze/VariableBlurView/assets/68231035/7460323f-e6cc-4630-8b9f-143f84ef4698
A workaround is to listen to changes to the user interface style and re-apply the filter then. I put everything from the init function into updateFilter() to call it again. It's important you add a tiny delay, otherwise it won't work.
registerForTraitChanges(
[UITraitUserInterfaceStyle.self]
) { (self: Self, previousTraitCollection: UITraitCollection) in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01, execute: {
self.updateFilter()
})
}
Found a nice hack in SwiftUI, I put the view initializer in an if
block so that it redraws when the color scheme changes.
That also somehow fixes the issue when switching out and back to the app!
struct BlurGradientView: View {
@Environment(\.colorScheme) var colorScheme
let gradient = LinearGradient(
gradient: Gradient(stops: [
.init(color: .black, location: 0.8),
.init(color: .clear, location: 1.0)
]),
startPoint: .top,
endPoint: .bottom
)
var body: some View {
if colorScheme == .dark {
VariableBlurView()
.mask(gradient)
.allowsHitTesting(false)
} else {
VariableBlurView()
.mask(gradient)
.allowsHitTesting(false)
}
}
}
can you reopen this so it's handled with the package itself? @katagaki
@0xifarouk Let me reopen this so you can submit a PR if you have any. I might look into it when I have time, but I'm working on other projects at the moment.
Found a nice hack in SwiftUI, I put the view initializer in an
if
block so that it redraws when the color scheme changes. That also somehow fixes the issue when switching out and back to the app!struct BlurGradientView: View { @Environment(\.colorScheme) var colorScheme let gradient = LinearGradient( gradient: Gradient(stops: [ .init(color: .black, location: 0.8), .init(color: .clear, location: 1.0) ]), startPoint: .top, endPoint: .bottom ) var body: some View { if colorScheme == .dark { VariableBlurView() .mask(gradient) .allowsHitTesting(false) } else { VariableBlurView() .mask(gradient) .allowsHitTesting(false) } } }
For just a bit more cleaner code, the one may replace the if
statement with something like
var body: some View {
VariableBlurView()
.mask(gradient)
.allowsHitTesting(false)
.id(colorScheme)
}
so VariableBlurView()
re-renders whenever colorScheme
changes.