SwiftUI查漏补缺(1) - 实现呼吸灯效果

1个月前 120次点击 来自 SwiftUI

收录专题: SwiftUI查漏补缺

最近在开发中我需要一个呼吸灯效果,用于着重提醒,效果图如下:

SwiftUI呼吸灯效果

struct SwiftUIView: View {
    @State private var animationAmount: CGFloat = 1
    @State private var animationActive: Bool = true

    var body: some View {
        VStack {
            Button(self.animationActive ? "Stop" : "Start") {
                self.animationActive.toggle()
            }
            .padding(40)
            .background(Color.red)
            .foregroundColor(.white)
            .clipShape(Circle())
            .overlay(
                Circle()
                    .stroke(Color.red)
                    .scaleEffect(animationActive ? animationAmount : 1)
                    .opacity(animationActive ? Double(2 - animationAmount) : 1)
                    .animation(animationActive ? Animation.easeOut(duration: 1).repeatForever(autoreverses: false) : Animation.default)
            )
            .onAppear {
                self.animationAmount = 2
            }
        }
    }
}

实现说明

重点方法:

  1. .overlay() (Layers a secondary view in front of this view.) 在这个视图前面加载一个次要视图。
  2. .animation() (Applies the given animation to all animatable values within this view.) 将给定的动画应用于此视图中的所有可动画值。

呼吸灯效果主要由2个效果进行叠加:

  1. .scaleEffect() 用于Scale增大
  2. .opacity() 用于Opacity增加不透明度

具体思路请看代码即可

方法改进

扩展Animationrepeat方法:

extension Animation {
    func `repeat`(while expression: Bool, autoreverses: Bool = true) -> Animation {
        if expression {
            return repeatForever(autoreverses: autoreverses)
        } else {
            return self
        }
    }
}

struct SwiftUIView: View {
    @State private var animationAmount: CGFloat = 1
    @State private var animationActive: Bool = true

    var body: some View {
        VStack {
            Button(self.animationActive ? "Stop" : "Start") {
                self.animationActive.toggle()
            }
            .padding(40)
            .background(Color.red)
            .foregroundColor(.white)
            .clipShape(Circle())
            .overlay(
                Circle()
                    .stroke(Color.red)
                    .scaleEffect(animationActive ? animationAmount : 1)
                    .opacity(animationActive ? Double(2 - animationAmount) : 1)
//                    .animation(animationActive ? Animation.easeOut(duration: 1).repeatForever(autoreverses: false) : Animation.default)
                    .animation(Animation.easeOut(duration: 1).repeat(while: animationActive, autoreverses: false))
            )
            .onAppear {
                self.animationAmount = 2
            }
        }
    }
}

参考链接:

Card image cap
开发者雷

尘世间一个小小的开发者

技术文档 >> 系列应用 >>
热推应用

EntryS

学习Swift的入门教程
标签