skip to Main Content

When I move a view with ultra thin material background, it turns black. Is it a bug or am I doing something wrong?

Is there a workaround to achieve this view on a moving view?

I noticed only happens when there is angular motion. If I delete rotation effect the problem goes away.

Testable code:

struct Test: View {
    
    @State var offset: CGFloat = 0
    @GestureState var isDragging: Bool = false
    
    var body: some View {
        GeometryReader { reader in
            ZStack {
                Image(systemName: "circle.fill")
                    .font(.largeTitle)
                    .frame(width: 300, height: 300)
                    .background(.red)
                    .overlay(alignment: .bottom) {
                        Rectangle()
                            .frame(height: 75)
                            .background(.ultraThinMaterial)
                    }
                    .clipShape(
                        RoundedRectangle(cornerRadius: 15, style: .continuous)
                    )
                    .compositingGroup()
                    .offset(x: offset)
                    .rotationEffect(.degrees(getRotation(angle: 8)))
                    .compositingGroup()
                    .gesture(
                        DragGesture()
                            .updating($isDragging) { _, state, _ in
                                state = true
                            }
                            .onChanged { value in
                                let translation = value.translation.width
                                offset = (isDragging ? translation : .zero)
                            }
                            .onEnded { value in
                                let width = getRect().width
                                let translation = value.translation.width

                                let checkingStatus = translation > 0 ? translation : -translation

                                withAnimation {
                                    if checkingStatus > (width / 2) {
                                        offset = (translation > 0 ? width : -width) * 2
                                    } else {
                                        offset = 0
                                    }
                                }
                            }
                    )
                    
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    
    private func getRotation(angle: Double) -> Double {
        let rotation = (offset / getRect().width) * angle
        return rotation
    }
}

enter image description here

2

Answers


  1. Code is not testable so hard to say definitely, but

    1. try to move all that image with modifiers into separated standalone view

    2. try composite it

       .clipShape(
           RoundedRectangle(cornerRadius: 15, style: .continuous)
       )
       .compositingGroup()       // << here !!
       .offset(y: -topOffset)
      
    Login or Signup to reply.
  2. For me, just adding .compositingGroup() modifier changed nothing, I still had a glitch

    In my case, I also use blur, shadows and other modifiers as well as rotationEffect. Sure, the glitch is connected with rotation

    I managed to solve the problem via changing the order or view modifiers. Make sure that rotationEffect(_:axes:) is used before others

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search