美文网首页
SpinnerView 示例

SpinnerView 示例

作者: _浅墨_ | 来源:发表于2023-08-12 21:35 被阅读0次

最终效果:

源码:

import SwiftUI

struct SpinnerView: View {
    
  // 定义 Leaf 结构体
  struct Leaf: View {
    let rotation: Angle
    let isCurrent: Bool

    var body: some View {
        /*
         逐行解释以下代码:

         1. `Capsule()`:创建一个椭圆形状的视图。

         2. `.stroke(isCurrent ? Color.white : .gray, lineWidth: 8)`:给椭圆形状视图添加一个描边,同时根据`isCurrent`的值来决定描边的颜色是白色还是灰色,描边的线宽为8。

         3. `.frame(width: 20, height: 50)`:设置视图的大小,将其宽度设置为20,高度设置为50。

         4. `.offset(isCurrent ? .init(width: 10, height: 0) : .init(width: 40, height: 70))`:根据`isCurrent`的值来设置视图的偏移量。如果`isCurrent`为`true`,则将视图在X轴上向右偏移10,Y轴上不偏移;如果`isCurrent`为`false`,则将视图在X轴上向右偏移40,Y轴上向下偏移70。

         5. `.scaleEffect(isCurrent ? 0.5 : 1)`:根据`isCurrent`的值来设置视图的缩放比例。如果`isCurrent`为`true`,则将视图缩放为原来的一半;如果`isCurrent`为`false`,则保持原始大小。

         6. `.rotationEffect(rotation)`:根据给定的角度`rotation`对视图进行旋转。这里可以根据需要传入一个`Angle`类型的值来控制旋转角度。

         7. `.animation(.easeInOut(duration: 1.5), value: isCurrent)`:为视图添加动画效果。`.animation`修饰符用于指定动画效果的类型和持续时间。在这里,使用了`easeInOut`类型的动画,持续时间为1.5秒。通过`value`参数,动画将在`isCurrent`的值发生变化时触发。
         */
      Capsule()
        .stroke(isCurrent ? Color.white : .gray, lineWidth: 8)
        .frame(width: 20, height: 50)
        .offset(
          isCurrent
            ? .init(width: 10, height: 0)
            : .init(width: 40, height: 70)
        )
        .scaleEffect(isCurrent ? 0.5 : 1)
        .rotationEffect(rotation)
      // MARK: - Update deprecated `animation` modifier
      //        .animation(.easeIn(duration: 1.5))
      // Animate when `isCurrent` or `isCompleting` change
        .animation(.easeInOut(duration: 1.5), value: isCurrent)
    }
  }

  // 叶子的数量
  let leavesCount = 12
  //初始值-1的@State属性currentIndex,用于跟踪当前显示的叶子索引
  @State var currentIndex = -1
  
  var body: some View {
    VStack {
      ZStack {
        ForEach(0..<leavesCount) { index in
          Leaf(
            rotation: .init(degrees: .init(index) / .init(leavesCount) * 360),
            isCurrent: index == currentIndex
          )
        }
      }
      .onAppear(perform: animate)
    }
  }
  
  func animate() {
    Timer.scheduledTimer(withTimeInterval: 0.15, repeats: true) { timer in
      currentIndex = (currentIndex + 1) % leavesCount
    }
  }
}

struct SpinnerView_Previews : PreviewProvider {
  static var previews: some View {
    SpinnerView()
  }
}

相关文章

网友评论

      本文标题:SpinnerView 示例

      本文链接:https://www.haomeiwen.com/subject/zetfmdtx.html