SwiftUI 中子视图的过渡动画

问题描述 投票:0回答:1

我已经研究这个问题很长时间了,但无法在这里或在线找到任何解决如何在子视图出现/消失时创建自定义过渡的答案。

我想做的...我有一个徽章视图

TestBadgeView
和一个
TestBadgeInsideHStackView
,顾名思义,它只是一个嵌入了
TestBadgeView
的HStack。在预览屏幕上,使用
TestTransitionView
,我有一个文本字段,允许更新徽章内显示的文本。屏幕中间的徽章始终可见,但可以使用“显示/隐藏我”按钮隐藏/使其可见。该过渡通过调用
.transition(.scale)
修饰符来使用缩放动画。对于屏幕右上角的徽章(位于文本徽章--->的右侧,位于
TestBadgeInsideHStackView
内),我试图让该徽章仅在用户输入
hello world
时显示进入文本字段。这可以工作,但我无法让过渡动画工作。这是我的代码的简化版本,但我最终试图让父视图将数据传递到子视图,然后基于逻辑要么可见,要么不可见,但可见性应该通过过渡进行动画处理。有什么想法吗?

您应该能够剪切并粘贴下面的代码来测试/试用。

import SwiftUI

struct TestTransitionView: View {
    
    @State var showView: Bool = true
    @State var text: String = "hello"
    
    var body: some View {
        
            VStack {
                               
                TextField("textfield", text: $text)
                    .padding()
                    .border(.gray)
                    .padding()
                
                TestBadgeInsideHStackView(shouldShowBadge: text == "hello world") {
                    Text(text.uppercased())
                }
                
                HStack {
    
                    if showView {
                        Text(text.uppercased())
                            .padding(.horizontal, 10)
                            .padding(.vertical, 7)
                            .background(Rectangle()
                                .fill(.gray).opacity(0.1)
                                .cornerRadius(6)
                            )
                            .font(.caption)
                            .fontWeight(.bold)
                            .transition(.scale)
                    }
                }
                .frame(height: 100)
                .padding()
                
                Spacer()
                Button("Show/Hide Me") {
                    withAnimation {
                        showView.toggle()
                    }
                }.padding(50)
            }
    }
}


struct TestBadgeInsideHStackView<Content: View> : View {
    let content: Content
    private var shouldShowBadge: Bool
    
    init(shouldShowBadge: Bool, @ViewBuilder content: () -> Content) {
        self.content = content()
        self.shouldShowBadge = shouldShowBadge
    }
    
    var body: some View {
        HStack {
            Text("badge ---> ")
            Spacer()
            if shouldShowBadge {
                TestBadgeView {
                    content
                }
                .transition(.scale)
            }
        }
        .frame(height: 100)
        .padding()
    }
}


struct TestBadgeView<Content: View>: View {
    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
        
    var body: some View {
        content
            .padding(.horizontal, 10)
            .padding(.vertical, 7)
            .background(Rectangle()
                .fill(.gray).opacity(0.1)
                .cornerRadius(6)
            )
            .font(.caption)
            .fontWeight(.bold)
            .transition(.scale)
    }
}



#Preview {
    TestTransitionView()
}

swiftui transition
1个回答
0
投票

要对过渡进行动画处理,您只需将

.animation
修饰符添加到
HStack
中的
TestBadgeInsideHStackView

// TestBadgeInsideHStackView

var body: some View {
    HStack {
        // content as before
    }
    .animation(.easeInOut, value: shouldShowBadge) // <- ADDED
    // other modifiers as before
}

我还建议使用

private let
:

定义此结构中的两个属性
private let content: Content
private let shouldShowBadge: Bool
© www.soinside.com 2019 - 2024. All rights reserved.