j0h4nn3s
j0h4nn3s

Reputation: 2076

Change the Opacity of a View with a Swift Material without Altering The Visual Effect

I am trying to animate the transition of a (image) view in SwiftUI which is blurred using a system material visual effect:

ZStack {
   Image(uiImage: UIImage(named: "Landscape-Color.jpg")!)
      .resizable()
      .aspectRatio(contentMode: .fit)
      .frame(width: 200, height: 200)
   VisualEffectView(UIBlurEffect(style: .systemThinMaterial))
   Text("Hello, world!")
}.opacity(0.5)

You can find a playground with a complete code example here.

The transition should animate the opacity of the view, without changing the blur effect of the swift material. As you can see with the code example and the in the picture below, setting an opacity lessens the blur effect and makes the underlying content more visible. In my example, the visual effect should not change when the view is removed.

Same ZStack with Visual effect view, the first one as a .opacity(0.5)

I am looking for a solution how to lower the opacity of the ZStack without changing the look of the visual effect. (only the blue background behind should be more visible, not the picture within the view).

Any help is greatly appreciated, and I don't mind if the solution is in SwiftUI or UIKit, as long as I can embed everything somewhere in SwiftUI. Please let me know, if anything is unclear.

Upvotes: 0

Views: 1378

Answers (1)

lorem ipsum
lorem ipsum

Reputation: 29309

Have you tried putting he picture in the .background?

import SwiftUI

@available(iOS 15.0, *)
struct OpacityView: View {
    @State var opacity: CGFloat = 0.5
    var body: some View {
        VStack{
            Slider(value: $opacity)
            ZStack {
                Color.blue
                //Other View elements here
                Text("Hello, world!")
            }.opacity(opacity)
            
        }.background(
            Image(systemName: "person")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 200, height: 200)
                .overlay(Material.ultraThin)
        )
        
    }
}
@available(iOS 15.0, *)
struct OpacityView_Previews: PreviewProvider {
    static var previews: some View {
        OpacityView()
    }
}

It seems to provide the effect you want.

opacity == 0

enter image description here

opacity == 0.5

enter image description here

opacity == 1

enter image description here

At 1 the image is hidden by the Color since it is behind the ZStack. If this isn't what you want can you

Upvotes: 0

Related Questions