你好!
我有两个按钮,一个是X,一个是取消。根据我按下的按钮,我希望X按钮有不同的过渡。
按X时:我想删除的X按钮是。不透明。动画(。默认)
当按下“取消”时:我希望X按钮的移除是.move(edge:.trailing).combined(with:.opacity).animation(.default)
对于上下文,它是一个textField,当我输入一些东西时,X按钮会出现。
我已经尝试使用State变量,在Button操作中的withAnimation中设置过渡。这似乎为下一个周期/刷新而不是当前周期/刷新设置了转换。我也研究过交易,但我只能从那里操纵动画?
所以当我按下X按钮时,下一次我按下X或取消时,它将是我设置的过渡。而当我按下取消时,下一次它会将过渡设置为他们的另一个。
正如您在GIF中看到的,它循环切换,但我希望为每个按钮设置它们。
预期行为:
当按X时,我希望它使用. opacity淡出。
当按下“取消”时,我希望X按钮“滑出”,使用.move作为删除过渡。
import Combine
import Foundation
import SwiftUI
struct SearchBar: View {
@Binding var searchField: String
let clearSearchField: () -> Void
let isFocus: Bool
let setFocus: (Bool) -> Void
@State var transition: AnyTransition = .opacity.animation(.default)
var body: some View {
HStack(spacing: 16) {
ZStack {
Color.gray
VStack(alignment: .leading) {
HStack {
TextField(
"Placeholder",
text: $searchField,
onEditingChanged: { _ in setFocus(true) }
)
.foregroundColor(.white)
Spacer()
if searchField.isNonEmpty {
Button {
transition = .opacity.animation(.default)
withAnimation {
clearSearchField()
}
} label: {
Text("X")
}
.transition(
.asymmetric(
insertion: .opacity.animation(.default),
removal: transition
)
)
}
}
}
.padding(16)
}
.cornerRadius(8)
if isFocus {
Button(
action: {
transition = .move(edge: .trailing).combined(with: .opacity)
hideKeyboard()
clearSearchField()
setFocus(false)
},
label: {
Text("Cancel")
.foregroundColor(.white)
}
)
.transition(.move(edge: .trailing).combined(with: .opacity).animation(.default))
}
}
.frame(height: 48)
.foregroundColor(searchField.isEmpty ? .grey: .white)
.padding(16)
.animation(.default, value: [isFocus])
}
}
这可能吗?
感谢任何帮助!
2条答案
按热度按时间brccelvz1#
根据我的观察,你不可能改变一个观点的转变而不改变它的身份。一旦视图出现了一个过渡,你不能告诉它消失与另一个过渡。
所以解决这个问题的一种方法是有 * 两个 * X按钮,一个带有
.opacity
转换,另一个带有.move
。使用@State
来决定显示哪个按钮:范例:
另一种方法是在每次想要更改过渡时为X按钮提供一个新的
id
,从而创建一个“新”视图。y0u0uwnf2#
解决这个问题的一种方法是在物品周围放置多层容器。不同的容器可以具有不同的过渡。
这表明它正在工作:
在不透明度过渡的情况下,周围的容器(将具有移动过渡)仍然存在,但为空。如果你也想隐藏它,那么你可以有一个额外的布尔标志,比如
containersAreVisible
,你可以在嵌套内容的onDisappear
回调中将其设置为false。如果您只希望部分内容消失(比如X按钮,而不是Cancel按钮),那么您可以将Cancel按钮移动到更高一级的容器中,以便它包含在一个过渡中,但从另一个过渡中排除。
另一个例子是这个方法的实际应用,参见SwiftUI bi-directional move transition moving the wrong way in certain cases的解决方案。