携手创作,一起成长!这是我参加「日新计划 8 月更文挑战」的第13天,点击查看活动详情。

在本章中,你将学会运用SwiftUI建立一个倒计时App

项目布景

每当周末,总要在家里煮顿饭,才对得起满冰箱的菜,和打扫得干干净净的厨房。

在做海鲜的时候,常常会需求准确计时,煮久了不好吃,煮得时刻太短又不熟。

这时候,就需求有一个倒计时的App,帮助咱们很好地控制时刻。

那么本章,咱们就来运用SwiftUI建立一个倒计时App

项目建立

首要,创立一个新的SwiftUI项目,命名为CountDown

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

款式预览

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

布景圆环

布景圆环的款式,咱们可以运用Circle圆形形状来建立,示例:

// 布景圆环
func progressTrackView() -> some View {
Circle()
.fill(Color.clear)
.frame(width: 250, height: 250)
.overlay(Circle().stroke(Color.black.opacity(0.09), lineWidth: 15))
}

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

上述代码中,咱们创立了一个新的视图progressTrackView

咱们运用Circle构建布景圆环,运用fill修饰符填充颜色去掉布景,再运用frame修饰符设置巨细,最终运用overlay修饰符赋予了圆环线宽做边框。

进展圆环

完结布景圆环后,咱们来完结进展圆环。

首要咱们需求两个倒计时参数,一个是总倒计时时刻,一个是倒计时当时时刻,示例:

@State var totalCountdown: CGFloat= 30
@State var counter: Int = 10

然后咱们还需求创立一个办法取得开端时的进展方位,示例:

// 取得开端进展
func startProgress() -> CGFloat {
return (CGFloat(counter) / CGFloat(totalCountdown))
}

同样,咱们还需求创立一个办法来取得结束时的进展方位,示例:

// 取得结束进展
func completed() -> Bool {
return startProgress() == 1
}

完结这些根底预备后,咱们就可以来构建进展圆环视图了,示例:

// 进展圆环
func progressBarView() -> some View {
Circle()
.fill(Color.clear)
.frame(width: 250, height: 250)
.overlay(
Circle()
.trim(from: 0, to: startProgress())
.stroke(style: StrokeStyle(lineWidth: 15, lineCap: .round, lineJoin: .round))
.rotationEffect(.init(degrees: -90))
.foregroundColor(
withAnimation(.easeInOut(duration: 0.2)) {
completed() ? Color.green : Color.orange
}
)
)
}

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

上述代码中,咱们构建了一个进展圆环视图progressBarView

咱们依旧运用Circle来构建圆环,咱们在Circle圆环的根底上overlay掩盖一个圆环,外边的圆环需求和布景圆环尺寸保持一致。

进展圆环运用trim绘制进展,运用stroke修饰符绘制边框,运用rotationEffect进展旋转取得进展改变,运用foregroundColor绘制布景颜色,当进展为0的时候变成绿色。

进展时刻

完结布景圆环和进展圆环后,还需求显现当时的进展时刻,咱们可以创立一个办法来取得格式化的时刻,示例:

// 取得格式化时刻
func counterToMinutes() -> String {
let currentTime = Int(totalCountdown) - counter
let seconds = currentTime % 60
let minutes = Int(currentTime / 60)
return "\(minutes):\(seconds < 10 ? "0" : "")\(seconds)"
}

上述代码中,咱们构建了一个格式化字符串的办法counterToMinutes,主要为了根据秒钟转换为格式化的字符串。

然后咱们构建进展时刻款式,示例:

// 进展时刻
func progressTimeView()-> some View {
Text(counterToMinutes())
.font(.system(size: 48))
.fontWeight(.black)
}

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

操作按钮

倒计时App的操作按钮和之前做过的计时器App的操作类似,一个开端按钮,点击开端按钮后,开端按钮变成暂停按钮。

另一个是重置按钮,点击重置后,回归初始状况。

首要咱们需求先声明一个开端状况的参数,示例:

@State var isStart = false

然后运用Image和体系图标构建款式部分,示例:

// 操作按钮
func btnView() -> some View {
HStack(spacing: 55) {
// 开端按钮
Image(systemName: self.isStart ? "pause.fill" : "play.fill")
.font(.system(size: 40))
.foregroundColor(.white)
.frame(minWidth: 0, maxWidth: 80, minHeight: 0, maxHeight: 80)
.background(self.isStart ? .red : .green)
.clipShape(Capsule())
.onTapGesture {
self.isStart.toggle()
}
// 重置按钮
Image(systemName: "arrow.clockwise")
.font(.system(size: 40))
.foregroundColor(.white)
.frame(minWidth: 0, maxWidth: 80, minHeight: 0, maxHeight: 80)
.background(.blue)
.clipShape(Capsule())
.onTapGesture {
self.counter = 0
withAnimation(.default) {
self.totalCountdown = 30
}
}
}.padding(.bottom, 55)
}

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

上述代码中,咱们构建了一个操作栏视图btnView

这里运用HStack横向视图排布了2个按钮,当咱们点击开端按钮时,款式会随isStart改变,以便于咱们操作开端和暂停。

重置按钮,咱们也加了一个点击事件,点击时将当时进展counter设置为0,总进展totalCountdown设置回30。

开端计时

为达到倒计时作用,咱们需求创立一个办法,当咱们开端计时时,若当时进展小于总进展,则当时进展累加,示例:

// 开端计时
func startCounting() {
if self.isStart {
if (self.counter < Int(self.totalCountdown)) {
self.counter += 1
}else {
self.isStart.toggle()
}
}
}

然后咱们声明一个变量,返回以给定间隔重复发出当时日期的发布者,示例:

@State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

最终,咱们将计时办法加到视图中,并排布已经创立好的元素。示例:

var body: some View {
VStack {
Spacer()
ZStack {
progressTrackView()
progressBarView()
progressTimeView()
}
Spacer()
btnView()
}.onReceive(timer) { time in
self.startCounting()
}
}

项目预览

使用SwiftUI搭建一个倒计时App,让你做饭时不再焦虑~

祝贺你,完结了整个项目的全部内容!

快来着手试试吧。

假如本专栏对你有帮助,不妨点赞、谈论、重视~