iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Mobile Development

使用 SwiftUI 讓有趣的點子變成 Apps系列 第 8

D8 - 使用 SwiftUI 讓有趣的點子變成 Apps{葛麗絲逆走鐘: 錶盤上的刻度}

  • 分享至 

  • xImage
  •  

人類在錶盤上還會設計刻度,雖然這個刻度並不是必要的,不過做出來並不困難,只是畫一條線而已,今天就來實作這邊的程式碼。

struct Tick: Shape {
  
  var tickLength: CGFloat
  
  func path(in rect: CGRect) -> Path {
    
    var p = Path()
    p.move(to: CGPoint(x: rect.midX, y: rect.minY))
    p.addLine(to: CGPoint(x: rect.midX, y: rect.minY + tickLength))
    
    return p
  }
}

struct Tick_Previews: PreviewProvider {
  static var previews: some View {
    Tick(tickLength: 20)
      .stroke(lineWidth: 3)
      .previewLayout(.fixed(width: 200, height: 200))
  }
}

Tick 是一個 shape,在 init()後,可以用 stroke() 去調整粗細。然後,我們把他畫在 ClockDialView() 裡面。

因為刻度本身會不斷的畫,可以先抽出成一個 some View 的 property。之後再組合進 body 裡面。如果一個 View 裡面的 body 有非常大量的 View,可讀性也會變差的。解決方法是用 @ViewBuilder 的 func 宣告,或是寫一個 property 宣告 some View 後,再組合進 body 裡面。

這邊選擇使用 property,下面的 ticks,就是錶盤上的刻度

struct ClockDialView: View {
  
  var tickLength: CGFloat = 10
  
  var body: some View {
    
    ZStack {
      Circle()
        .stroke()
        .padding(3)
      
      ticks
        .padding(3)
      
      HStack {
        Spacer()
        BackwardsClockNumberView()
        Spacer()
      }
    }
  }
  
  var ticks: some View {
    ![https://ithelp.ithome.com.tw/upload/images/20220909/20140622rPBNfTfIwD.png](https://ithelp.ithome.com.tw/upload/images/20220909/20140622rPBNfTfIwD.png)
    ForEach(0..<60) { position in
        if position % 5 == 0 {
            Tick(tickLength: tickLength)
                .stroke(lineWidth: 3)
                .rotationEffect(.radians(Double.pi * 2 / 60 * Double(position)))
        }
    }
  }
}

這樣就能在每個數字上,畫出一個刻度,總共 12 個刻度。

https://ithelp.ithome.com.tw/upload/images/20220909/20140622OffLcxhxA4.png

如果希望畫出細一點的, 60 個刻度,然後在數字上的刻度比較長,這也很容易做,調整一下 ticks 的程式碼即可。

先寫一個判斷是不是 5 的倍數的 func,只要把 position 傳進去,在確認是 5 的倍數的 position,把 tick length 變長即可,這邊使用的是 1.8 倍長度差。

struct ClockDialView: View {
  
  var tickLength: CGFloat = 5
  
  var body: some View {
    
    ZStack {
      Circle()
        .stroke()
        .padding(3)
      
      ticks
        .padding(3)
      
      HStack {
        Spacer()
        BackwardsClockNumberView()
        Spacer()
      }
    }
  }
  
  private func isLongTick(_ position: Int) -> Bool {
    return position % 5 == 0
  }
 
  var ticks: some View {

    ForEach(0..<60) { position in
      let longerTick = tickLength * 1.8

      Tick(tickLength: isLongTick(position) ? longerTick : tickLength )
        .stroke(lineWidth: 3)
        .rotationEffect(.radians(Double.pi * 2 / 60 * Double(position)))
    }
  }
}

結果如下

https://ithelp.ithome.com.tw/upload/images/20220909/20140622mDco9s1gF6.png


上一篇
D7 - 用 SwiftUI 讓有趣的點子變成 Apps{葛麗絲逆走鐘: 錶盤}
下一篇
D9 - 用 SwiftUI 讓有趣的點子變成 Apps{葛麗絲逆走鐘:組合錶盤和時分秒針}
系列文
使用 SwiftUI 讓有趣的點子變成 Apps30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言