在 SwiftUI 中使文本脉动

问题描述 投票:0回答:2

所以我试图让一些文本淡入和淡出以产生脉动类型的效果,这是我现在的代码:

struct SignInView: View {
    @State private var opacity: Double = 0.0
    @State private var pulseDown: Bool = false
    
    var body: some View {
        VStack(alignment: .center) {
            Spacer()
            
            Button(action: {
                AppDelegate.signInWithGoogle()
            }, label: {
                Text("Sign In")
                    .foregroundColor(Color.green)
                    .opacity(opacity)
            })
            
            Spacer()
        }
        .padding()
        .onAppear {
            self.pulsateText()
        }
    }
    
    private func pulsateText() {
        DispatchQueue.init(label: "Pulse").asyncAfter(deadline: .now() + 0.01) {
            if self.pulseDown {
                self.opacity -= 0.02
            } else {
                self.opacity += 0.02
            }
            
            if self.opacity > 1 {
                self.pulseDown = true
            } else if self.opacity < 0.1 {
                self.pulseDown = false
            }
            
            self.pulsateText()
        }
    }
}

它完全符合我的要求并且看起来不错,但我忍不住觉得无限递归循环不是正确的方法。我想我可以用无限的 while 而不是无限递归,尽管这看起来仍然不理想。有没有更好的方法来实现这个目标?

swift animation swiftui
2个回答
7
投票

有一种更简单、更像 SwiftUI 的方式。它通过使用

Animation
repeatForever(autoreverses:)
方法来工作:

struct SignInView: View {

    @State private var visible = true
    
    var body: some View {
        VStack {
            Spacer()
            
            Button(action: {
                print("Sign in with Google")
//                AppDelegate.signInWithGoogle()
            }, label: {
                Text("Sign In")
                    .foregroundColor(Color.green)
                    .opacity(visible ? 1 : 0)
            })
            
            Spacer()
        }
        .padding()
        .onAppear(perform: pulsateText)
    }
    
    private func pulsateText() {
        withAnimation(Animation.easeInOut.repeatForever(autoreverses: true)) {
            visible.toggle()
        }
    }
}

0
投票

这是一个简单的 ViewModifier 版本,它将逻辑隔离到类似于原生的

pulseEffect()
中:
scaleEffect()

© www.soinside.com 2019 - 2024. All rights reserved.