SwiftUI - 使用淡入淡出动画更改文本
Posted
技术标签:
【中文标题】SwiftUI - 使用淡入淡出动画更改文本【英文标题】:SwiftUI - Change Text with fade animation 【发布时间】:2020-08-21 21:26:01 【问题描述】:我想看看我是如何做到的,以便通过淡入和淡出更改文本视图的源代码。
因此,如果我有如下简单视图:
struct TestView: View
@State var text = "I am a shrubber."
func changeText()
text = (text == "I am a shrubber.") ? "My name is Roger the Shrubber." : "I am a shrubber."
var body: some View
VStack
Text(self.text)
TestButton(label: "Change", action: changeText)
如果我点击按钮,文本会立即改变。
现在,如果我将更改的代码包装在 withAnimation
块中,或者将 .animation
视图修饰符添加到 Text 视图,它只会对帧大小的更改进行动画处理。这不是我要找的:
struct TestView: View
@State var text = "I am a shrubber."
func changeText()
withAnimation
text = (text == "I am a shrubber.") ? "My name is Roger the Shrubber." : "I am a shrubber."
var body: some View
VStack
Text(self.text)
TestButton(label: "Change", action: changeText)
当然,我可以通过使用.transition
视图修饰符和单独的文本字段(此答案:https://***.com/a/60984127/5919644)来接近我正在寻找的效果,如下所示:
struct TestView: View
@State var changed = false
var body: some View
VStack
if !changed
Text("I am a shrubber.")
.transition(AnyTransition.opacity.animation(.easeInOut(duration:0.3)))
if changed
Text("My name is Roger the Shrubber.")
.transition(AnyTransition.opacity.animation(.easeInOut(duration:0.3)))
TestButton(label: "Change", action: self.changed.toggle() )
但这是一种糟糕的模式,并且不适用于任意文本更改。即便如此,淡入和淡出也会同时发生。我想让淡出/淡入顺序发生。
【问题讨论】:
你试过使用动画时长吗?例如'.animation(Animation.easeInOut(duration: 3))' 【参考方案1】:好的,所以我想我自己找到了处理这个问题的最佳方法:通过绑定的发布者观察更改,然后手动淡出、更改文本和淡出。
视图如下所示:
struct FadingTextView: View
@Binding var source: String
var transitionTime: Double
@State private var currentText: String? = nil
@State private var visible: Bool = false
private var publisher: AnyPublisher<[String.Element], Never>
source
.publisher
.collect()
.eraseToAnyPublisher()
init(text: Binding<String>, totalTransitionTime: Double)
self._source = text
self.transitionTime = totalTransitionTime / 3
private func update(_: Any)
guard currentText != nil else
currentText = source
DispatchQueue.main.asyncAfter(deadline: .now() + (transitionTime))
self.visible = true
return
guard source != currentText else return
self.visible = false
DispatchQueue.main.asyncAfter(deadline: .now() + (transitionTime))
self.currentText = source
DispatchQueue.main.asyncAfter(deadline: .now() + (transitionTime))
self.visible = true
var body: some View
Text(currentText ?? "")
.opacity(visible ? 1 : 0)
.animation(.linear(duration: transitionTime))
.onReceive(publisher, perform: update(_:))
然后它可以用于任意文本更改,如下所示:
struct TestView: View
@State private var text: String = "Alpha"
private var values: [String] = ["Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel"]
private func updateText()
self.text = values.randomElement()!
var body: some View
VStack
FadingTextView(text: $text, totalTransitionTime: 1.0)
Button("Change", action: updateText).padding()
看起来像这样:
【讨论】:
以上是关于SwiftUI - 使用淡入淡出动画更改文本的主要内容,如果未能解决你的问题,请参考以下文章