VariableBlurView icon indicating copy to clipboard operation
VariableBlurView copied to clipboard

Unusual behavior when used in iOS 17 beta 1

Open katagaki opened this issue 1 year ago • 5 comments

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

katagaki avatar Jun 10 '23 01:06 katagaki

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()
            })
        }

nicoreese avatar Jun 10 '23 16:06 nicoreese

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)
        }
    }
}

katagaki avatar Jun 11 '23 15:06 katagaki

can you reopen this so it's handled with the package itself? @katagaki

0xifarouk avatar Aug 25 '23 14:08 0xifarouk

@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.

katagaki avatar Aug 25 '23 14:08 katagaki

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.

GalvinGao avatar Jun 16 '24 18:06 GalvinGao