美文网首页
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