美文网首页iOS开发
SwiftUI 绘制时钟

SwiftUI 绘制时钟

作者: _浅墨_ | 来源:发表于2024-06-28 14:47 被阅读0次

最终效果:

源码:


import SwiftUI

struct ContentView: View {
    var numbers = [12,1,2,3,4,5,6,7,8,9,10,11]
    var icons = ["calendar", "message", "figure.walk", "music.note"]
    @State var hour: Double = 0
    @State var minute: Double = 0
     
    var body: some View {
        ZStack {
            Rectangle()
                .fill(.gray.gradient)
                .ignoresSafeArea()
            
            clockCase
            
            RadialLayout {
                ForEach(numbers, id: \.self) { item in
                    Text("\(item)")
                        .font(.system(.title, design: .rounded))
                        .bold()
                        .foregroundColor(.black)
                }
            }
            .frame(width: 240)
            
            RadialLayout {
                ForEach(icons, id: \.self) { item in
                    Circle()
                        .foregroundColor(.black)
                        .frame(width: 44)
                        .overlay(Image(systemName: item)
                            .foregroundColor(.white))
                }
            }
            .frame(width: 120)
            
            Circle()
                .strokeBorder(.black, style: StrokeStyle(lineWidth: 10, dash: [1, 10]))
                .frame(width: 220)
            
            RadialLayout {
                ForEach(numbers, id: \.self) { item in
                    Text("\(item * 5)")
                        .font(.caption)
                        .foregroundColor(.black)
                }
            }
            .frame(width: 360)
            
            clockHands
        }
        .onAppear {
            hour = 360
            minute = 360
        }
    }
    
    var clockHands: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 4)
                .foregroundStyle(.black)
                .frame(width: 8, height: 70)
                .overlay(RoundedRectangle(cornerRadius: 4).stroke(lineWidth: 1).fill(.white))
                .offset(y: -32)
                .rotationEffect(.degrees(hour), anchor: .center)
                .shadow(radius: 5, y: 5)
                .animation(.linear(duration: 120), value: hour)
            
            RoundedRectangle(cornerRadius: 4)
                .foregroundStyle(.black)
                .frame(width: 8, height: 100)
                .overlay(RoundedRectangle(cornerRadius: 4).stroke(lineWidth: 1).fill(.white))
                .offset(y: -46)
                .rotationEffect(.degrees(minute), anchor: .center)
                .shadow(radius: 5, y: 5)
                .animation(.linear(duration: 10).repeatCount(12, autoreverses: false), value: minute)
            
            Circle()
                .fill(.white)
                .frame(width: 3)
        }
    }
    
    var clockCase: some View {
        ZStack {
            Circle()
                .foregroundStyle(
                    .gray
                    .shadow(.inner(color: .gray, radius: 30, x: 30, y: 30))
                    .shadow(.inner(color: .white.opacity(0.2), radius: 0, x: -1, y: -1))
                    .shadow(.inner(color: .black.opacity(0.2), radius: 0, x: 1, y: 1))
                )
                .frame(width: 360)
            
            Circle()
                .foregroundStyle(
                    .white
                    .shadow(.inner(color: .gray, radius: 30, x: -30, y: -30))
                    .shadow(.drop(color: .black.opacity(0.3), radius: 30, x: 30, y: 30))
                )
                .frame(width: 320)
            
            Circle()
                .foregroundStyle(.white.shadow(.inner(color: .gray, radius: 30, x: 30, y: 30)))
                .frame(width: 280)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct RadialLayout: Layout {
    
    func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
        return proposal.replacingUnspecifiedDimensions()
    }
    
    func placeSubviews(
        in bounds: CGRect,
        proposal: ProposedViewSize,
        subviews: Subviews,
        cache: inout Void
    ) {
        let radius = min(bounds.size.width, bounds.size.height) / 3.0
        let angle = Angle.degrees(360.0 / Double(subviews.count)).radians

        for (index, subview) in subviews.enumerated() {
            var point = CGPoint(x: 0, y: -radius)
                .applying(CGAffineTransform(
                    rotationAngle: angle * Double(index)))

            point.x += bounds.midX
            point.y += bounds.midY

            subview.place(at: point, anchor: .center, proposal: .unspecified)
        }
    }
}

代码注释:

这段代码是一个简单的时钟应用的 SwiftUI 实现。让我为您详细解释一下:

  1. 首先定义了一个 ContentView 结构体,其中包含了时钟的数字、图标以及时分针的状态信息。
  2. body 属性描述了视图的外观和布局。整体布局采用 ZStack,在屏幕上叠放多个视图。
  3. clockCase 方法定义了时钟的外壳,采用多层圆形的设计,带有阴影效果。
  4. clockHands 方法定义了时钟的时针和分针,通过旋转不同角度来表示时间的流逝。
  5. RadialLayout 结构体实现了自定义的布局方式,将子视图按照半径和角度进行排列。
  6. body 方法中,使用 RadialLayout 分别排列了时钟的数字和图标,以及时钟的刻度。
  7. onAppear 中初始化了时钟的时分针位置。
  8. 最后,定义了 ContentView_Previews 结构体用于预览视图。

这段代码展示了 SwiftUI 中如何使用 ZStack、Circle、RoundedRectangle 等视图来构建一个简单的时钟界面,并通过自定义布局方式 RadialLayout 实现了时钟数字和图标的排列。

相关文章

  • 用 SwiftUI 绘制树形图

    翻译自:Drawing Trees in SwiftUI 对于一个新项目,我们需要用 SwiftUI 来绘制树形图...

  • canvas绘制时钟

  • CSS绘制时钟

    效果图: 解析:1.利用transform: rotate(60deg);旋转实现刻度和指针2.hover时添加...

  • canvas绘制时钟

    这里简单了利用canvas做了一个时钟,样式配的比较难看主要讲了这么实现功能集体的细节根据自己的喜好来调试,请读者...

  • SwiftUI - 图形绘制

    在UIKit中的图形绘制大多都是基于Quartz2D的,它的API使用起来较为繁琐,使用不当时还会导致性能问题。S...

  • SwiftUI:图表绘制

    在这篇文章中,我将演示如何创建显示在一个流行的跑步和自行车应用程序中的活动历史图表。这次我将把它分解成小块,并在此...

  • SwiftUI 随手笔记-解决@ViewBuilder bloc

    SwiftUI 的@ViewBuilder 有一个限制,单个@ViewBuilder block 如果绘制超过10...

  • 使用canvas绘制时钟

    使用canvas绘制这样的一个时钟,这个时钟完全是通过代码绘制而成,没有使用图片: 不多说,贴代码: 把这段代码保...

  • 使用 SwiftUI 的 Eager Grids

    介绍 早在 2020 年,我们就拥有了在 SwiftUI(LazyVGrid 和 LazyHGrid)中绘制网格的...

  • canvas时钟面向对象方法

    用canvas绘制一个时钟是件非常简单的事情,自己尝试用下面向对象的方式去绘制时钟,会使这段代码的复用性更好. 这...

网友评论

    本文标题:SwiftUI 绘制时钟

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