SwiftUI中如何实现文本从小尺寸到大尺寸的动画效果?
实现文本从小尺寸到大尺寸的动画解决方案
为啥原来的小到大动画跑不起来?
你写的代码里,上面那个蓝色小文本固定了16号字体,还加了.minimumScaleFactor(0.1)——这个属性只允许文本缩小,压根不支持放大。所以当要从16号动画到36号时,固定字号的限制直接卡死了放大的可能,自然出不来想要的效果。
改法一:用单视图过渡(更简洁)
直接用一个视图负责过渡,同时在上方显示新文本,逻辑更清晰:
struct AnimView: View { @State private var currentText = "23" @State private var nextText = "23" @State private var isAnimating = false @Namespace private var ns1 var body: some View { VStack { // 上方新出现的小文本 Text(nextText) .font(.system(size: 16)) .foregroundColor(.blue) .opacity(isAnimating ? 1 : 0) // 负责动画的文本:从小变大+移动位置 Text(currentText) .matchedGeometryEffect(id: "text", in: ns1) .font(.system(size: isAnimating ? 36 : 16)) .foregroundColor(isAnimating ? .red : .blue) .animation(.easeInOut(duration: 0.5), value: isAnimating) Spacer().frame(height: 50) Button("Move Down") { // 先生成新文本 nextText = String("\(Int.random(in: 1..<99))") // 触发动画 isAnimating = true // 动画结束后重置状态,准备下一次 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { currentText = nextText isAnimating = false } } } .padding() } }
改法二:保留原双Text结构
如果你不想改整体结构,就把上面文本的固定字号改成动态切换,同时去掉minimumScaleFactor:
struct AnimView: View { @State private var textAnim = "23" @State private var matched = true @Namespace private var ns1 var body: some View { VStack { Text(textAnim) .matchedGeometryEffect(id: matched ? "text" : "temp", in: ns1, isSource: !matched) .font(.system(size: matched ? 36 : 16)) // 随状态变字号 .foregroundColor(matched ? .red : .blue) .animation(.easeInOut, value: matched) Spacer().frame(height: 50) Text(textAnim) .matchedGeometryEffect(id: "text", in: ns1, isSource: true) .font(.system(size: 36)) .foregroundColor(.red) .opacity(matched ? 0 : 1) // 动画时藏起来避免重复 Button("Move Down") { withAnimation(nil) { textAnim = String("\(Int.random(in: 1..<99))") matched = false } withAnimation { matched = true } } } } }
两种方案都能实现小文本平滑放大并移动到下方的效果,选哪种看你习惯。
内容的提问来源于stack exchange,提问作者Joya Roy
相关产品推荐
相关产品推荐

