Swift UI中的动画文本 [英] Animating Text in Swift UI

查看:126
本文介绍了Swift UI中的动画文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从Swift UI动画化TextTextField视图?

How would it be possible to animate Text or TextField views from Swift UI?

通过动画,我的意思是,当文本更改时,它将计数".

By animation I mean, that when the text changes it will "count up".

例如,给定一些标签,如何创建动画,当我将标签文本设置为"100"时,动画从0上升到100.我知道这在UIKit中可以使用图层和CAAnimations来实现,但是使用函数和更改TextTextField的文本在动画方面似乎没有任何作用.

For example given some label, how can an animation be created that when I set the labels text to "100" it goes up from 0 to 100. I know this was possible in UIKit using layers and CAAnimations, but using the .animation() function in Swift UI and changing the text of a Text or TextField does not seem to do anything in terms of animation.

我看过Animatable协议及其相关的animatableData属性,但是它似乎不符合TextTextField的要求.我正在尝试创建一个向上计数的标签,因此给定一些值,例如使用@State@Binding然后使用TextTextField来跟踪Double对该值的更改会将其内容(实际的字符串文本)从值所在的位置更改为设置的位置的动画.

I've taken a look at Animatable protocol and its related animatableData property but it doesn't seem like Text nor TextField conform to this. I'm trying to create a label that counts up, so given some value, say a Double the changes to that value would be tracked, either using @State or @Binding and then the Text or TextField would animate its content (the actual string text) from what the value was at to what it was set to.

为了更加清晰,我想重新创建一个动画形式的标签:

To make it clearer, I'd like to recreate a label that looks like this when animated:

推荐答案

在SwiftUI中有一种纯文本动画方法.这是在SwiftUI中使用AnimatableModifier协议实现的进度指示器的实现:

There is a pure way of animating text in SwiftUI. Here's an implementation of your progress indicator using the AnimatableModifier protocol in SwiftUI:

我写了一篇详尽的文章,记录了AnimatableModifier(及其错误)的用法.它还包括进度指示器.您可以在此处阅读: https://swiftui-lab.com/swiftui-animations-part3/

I've written an extensive article documenting the use of AnimatableModifier (and its bugs). It includes the progress indicator too. You can read it here: https://swiftui-lab.com/swiftui-animations-part3/

struct ContentView: View {
    @State private var percent: CGFloat = 0

    var body: some View {
        VStack {
            Spacer()
            Color.clear.overlay(Indicator(pct: self.percent))

            Spacer()
            HStack(spacing: 10) {
                MyButton(label: "0%", font: .headline) { withAnimation(.easeInOut(duration: 1.0)) { self.percent = 0 } }

                MyButton(label: "27%", font: .headline) { withAnimation(.easeInOut(duration: 1.0)) { self.percent = 0.27 } }

                MyButton(label: "100%", font: .headline) { withAnimation(.easeInOut(duration: 1.0)) { self.percent = 1.0 } }
            }
        }.navigationBarTitle("Example 10")
    }
}

struct Indicator: View {
    var pct: CGFloat

    var body: some View {
        return Circle()
            .fill(LinearGradient(gradient: Gradient(colors: [.blue, .purple]), startPoint: .topLeading, endPoint: .bottomTrailing))
            .frame(width: 150, height: 150)
            .modifier(PercentageIndicator(pct: self.pct))
    }
}

struct PercentageIndicator: AnimatableModifier {
    var pct: CGFloat = 0

    var animatableData: CGFloat {
        get { pct }
        set { pct = newValue }
    }

    func body(content: Content) -> some View {
        content
            .overlay(ArcShape(pct: pct).foregroundColor(.red))
            .overlay(LabelView(pct: pct))
    }

    struct ArcShape: Shape {
        let pct: CGFloat

        func path(in rect: CGRect) -> Path {

            var p = Path()

            p.addArc(center: CGPoint(x: rect.width / 2.0, y:rect.height / 2.0),
                     radius: rect.height / 2.0 + 5.0,
                     startAngle: .degrees(0),
                     endAngle: .degrees(360.0 * Double(pct)), clockwise: false)

            return p.strokedPath(.init(lineWidth: 10, dash: [6, 3], dashPhase: 10))
        }
    }

    struct LabelView: View {
        let pct: CGFloat

        var body: some View {
            Text("\(Int(pct * 100)) %")
                .font(.largeTitle)
                .fontWeight(.bold)
                .foregroundColor(.white)
        }
    }
}

这篇关于Swift UI中的动画文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆