Home > front end >  SwiftUI Images jumping with with dropdown view toggle
SwiftUI Images jumping with with dropdown view toggle

Time:08-09

I created a custom dropdown where when clicked a bottom view opens up. What I am observing is that during the open click the header images are jumping to center and then coming right back up:

Jumping images example

struct ListSample: View {
    
    var body: some View {
        List {
            Dropdown()
            Dropdown()
            Dropdown()
        }
    }
}

struct Dropdown: View {
    
    @State var showBox = false
    @State var rotateDeg = 0.0
    
    var body: some View {
        VStack {
            showHideBox
            VStack {
                if showBox {
                    Rectangle()
                        .frame(height: 200)
                }
            }
            Spacer()
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0)
        .clipped()
        .animation(.easeOut, value: showBox)
        .transition(.slide)
    }
    
    var showHideBox: some View {
        HStack {
            Image(systemName: "squareshape.split.2x2")
            Text(showBox ? "Hide Box" : "Show Box")
                .font(.caption)
            Spacer()
            Image(systemName: "chevron.right")
                .foregroundColor(.accentColor)
                .rotationEffect(.degrees(rotateDeg))
        }
        .onTapGesture {
            withAnimation {
                showBox.toggle()
                rotateDeg = showBox ? 90 : 0
            }
        }
        .padding(6)
    }
}

Not sure how to get around this because the text is staying in place, any suggestions would be helpful. Thank you.

CodePudding user response:

It is because of default .center alignment in top VStack, use instead .top, so always visible part be always stuck to the top and removable just expands towards the buttom:

VStack {
    showHideBox
    VStack {
        if showBox {
            Rectangle()
                .frame(height: 200)
        }
    }
    Spacer()
}
.frame(maxWidth: .infinity, alignment: .top) // << here !!

*note: minWidth/minHeight are by-default 0, so can be removed from a modifier.

  • Related