我已经研究这个问题很长时间了,但无法在这里或在线找到任何解决如何在子视图出现/消失时创建自定义过渡的答案。
我想做的...我有一个徽章视图
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()
}
要对过渡进行动画处理,您只需将
.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