简体   繁体   中英

SwiftUI - Animate view transition and position change at the same time

I have a yellow container with a green view inside. I want to move the container while also hiding/showing the inner green view, with an animation. Currently, I'm using .offset for the movement, and an if statement for the green view's transition.

The problem is, although the yellow container moves, the green view does not. It simply fades in and out at the destination offset. I want it to also move alongside the yellow container.

This is what I get currently This is what I want
黄色容器左右移动,而绿色内部视图淡入淡出。绿色视图保持在右侧 黄色容器随着绿色内部视图左右移动,绿色内部视图也会淡入淡出。

Here's my code:

struct ContentView: View {
    @State var showingSubview = false
    
    var body: some View {
        VStack {
            Button("Show Subview") {
                withAnimation(.easeInOut(duration: 2)) {
                    showingSubview.toggle()
                }
            }
            
            if showingSubview {
                Text("Subview")
                    .padding()
                    .background(Color.green)
            }
        }
        .padding()
        .background(Color.yellow)
        .offset(x: showingSubview ? 150 : 0, y: 0)
    }
}

How can I make the green view move along with the yellow container, as it fades in and out? Preferably, I'd like to keep using if or switch statements for the insertion/removal.

You can just change the height as it animates.

Code version #1

This will not fade and appears inside the yellow rectangle.

Code:

struct ContentView: View {
    @State var showingSubview = false

    var body: some View {
        VStack(spacing: 0) {
            Button("Show Subview") {
                withAnimation(.easeInOut(duration: 2)) {
                    showingSubview.toggle()
                }
            }

            Text("Subview")
                .padding()
                .background(Color.green)
                .padding(.top)
                .frame(height: showingSubview ? nil : 0, alignment: .top)
                .clipped()
        }
        .padding()
        .background(Color.yellow)
        .offset(x: showingSubview ? 150 : 0, y: 0)
    }
}

Result #1

结果 1

Code version #2

This version will fade out and appear at bottom edge, as your GIF shows.

Code:

struct ContentView: View {
    @State var showingSubview = false

    var body: some View {
        VStack(spacing: 0) {
            Button("Show Subview") {
                withAnimation(.easeInOut(duration: 2)) {
                    showingSubview.toggle()
                }
            }

            Text("Subview")
                .padding()
                .background(Color.green)
                .padding(.top)
                .frame(height: showingSubview ? nil : 0, alignment: .top)
                .padding(.bottom)
                .background(Color.yellow)
                .clipped()
                .opacity(showingSubview ? 1 : 0)
        }
        .padding([.horizontal, .top])
        .background(Color.yellow)
        .padding(.bottom)
        .offset(x: showingSubview ? 150 : 0, y: 0)
    }
}

Result #2

结果 2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM