用按钮暂停计时器

发布于 2025-02-09 02:11:48 字数 3232 浏览 2 评论 0原文

我正在制作一个计时器,但不确定在触发按钮时如何暂停它。 我试图制作一个布尔@state,但我仍然不确定在触发按钮时如何暂停计时器。请在下面查看我的代码...

struct TestView: View {
    @State var isTimeStarted = false
    @State var to: CGFloat = 0
    @State var timeDuration = 60
    @State var time = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State var isPaused = false
    @State private var count = 0
    var body: some View {
        ZStack {
            VStack {
                ZStack {
                    Circle()
                        .trim(from: 0, to: self.to)
                        .stroke(LinearGradient(gradient: Gradient(colors: [Color.white, Color.white.opacity(0.2)]), startPoint: .topLeading, endPoint: .bottomTrailing), style: StrokeStyle(lineWidth: 15.6, lineCap: .round))
                        .shadow(radius: 8)
                        .rotationEffect(.degrees(90))
                        .rotation3DEffect(Angle(degrees: 180), axis: (x: 1, y: 0, z: 110))
                        .frame(width: 70, height: 70)
                        .animation(.easeOut)
                        .padding()
                        .padding(.leading, 10)
                    Text("\(self.timeDuration, specifier: formatTime())")
                        .font(.system(size: 17.5, design: .rounded))
                        .fontWeight(.semibold)
                        .foregroundColor(.white)
                        .padding(.leading, 10)
                }
                Button {
                    isPaused = true
                } label: {
                    ZStack {
                        BlurView2(style: .systemThinMaterialDark)
                            .frame(width: 145, height: 45)
                            .background(Color.yellow)
                            .cornerRadius(30)
                            .padding(.horizontal)
                        Image(systemName: "pause")
                            .font(.title2)
                            .shadow(radius: 10)
                            .foregroundColor(.yellow)
                    }
                }
            }
        }
        .preferredColorScheme(.dark)
        .onAppear {
            self.timeDuration = 60
            withAnimation(.default) {
                self.to = 60
            }
            self.isTimeStarted = true
        }
        .onReceive(self.time, perform: { _ in
            if self.timeDuration != 0 {
                self.timeDuration -= 1
                withAnimation(.default) {
                    self.to = CGFloat(self.timeDuration)/60
                }
            } else {
                self.timeDuration = 60
                self.to = 60
            }
        })
    }
    func formatTime() -> String {
        let minutes = Int(timeDuration) / 60 % 60
        let seconds = Int(timeDuration) % 60
        return String(format: "%02i:%02i", minutes,seconds)
    }
}

struct BlurView2: UIViewRepresentable {
    var style: UIBlurEffect.Style
    func makeUIView(context: Context) -> UIVisualEffectView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: style))
        return view
    }
    func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
        
    }
}

I am making a timer but am unsure of how to pause it when the button is triggered.
I have attempted to make a boolean @State but I am yet unsure how to pause the timer when the button is triggered. Please review my code below...

struct TestView: View {
    @State var isTimeStarted = false
    @State var to: CGFloat = 0
    @State var timeDuration = 60
    @State var time = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State var isPaused = false
    @State private var count = 0
    var body: some View {
        ZStack {
            VStack {
                ZStack {
                    Circle()
                        .trim(from: 0, to: self.to)
                        .stroke(LinearGradient(gradient: Gradient(colors: [Color.white, Color.white.opacity(0.2)]), startPoint: .topLeading, endPoint: .bottomTrailing), style: StrokeStyle(lineWidth: 15.6, lineCap: .round))
                        .shadow(radius: 8)
                        .rotationEffect(.degrees(90))
                        .rotation3DEffect(Angle(degrees: 180), axis: (x: 1, y: 0, z: 110))
                        .frame(width: 70, height: 70)
                        .animation(.easeOut)
                        .padding()
                        .padding(.leading, 10)
                    Text("\(self.timeDuration, specifier: formatTime())")
                        .font(.system(size: 17.5, design: .rounded))
                        .fontWeight(.semibold)
                        .foregroundColor(.white)
                        .padding(.leading, 10)
                }
                Button {
                    isPaused = true
                } label: {
                    ZStack {
                        BlurView2(style: .systemThinMaterialDark)
                            .frame(width: 145, height: 45)
                            .background(Color.yellow)
                            .cornerRadius(30)
                            .padding(.horizontal)
                        Image(systemName: "pause")
                            .font(.title2)
                            .shadow(radius: 10)
                            .foregroundColor(.yellow)
                    }
                }
            }
        }
        .preferredColorScheme(.dark)
        .onAppear {
            self.timeDuration = 60
            withAnimation(.default) {
                self.to = 60
            }
            self.isTimeStarted = true
        }
        .onReceive(self.time, perform: { _ in
            if self.timeDuration != 0 {
                self.timeDuration -= 1
                withAnimation(.default) {
                    self.to = CGFloat(self.timeDuration)/60
                }
            } else {
                self.timeDuration = 60
                self.to = 60
            }
        })
    }
    func formatTime() -> String {
        let minutes = Int(timeDuration) / 60 % 60
        let seconds = Int(timeDuration) % 60
        return String(format: "%02i:%02i", minutes,seconds)
    }
}

struct BlurView2: UIViewRepresentable {
    var style: UIBlurEffect.Style
    func makeUIView(context: Context) -> UIVisualEffectView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: style))
        return view
    }
    func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
        
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

娇俏 2025-02-16 02:11:48

这应该很简单。保持计时器的启动,但如果要暂停,请返回您的功能。

将其添加到.onreceive函数的开始中:

if isPaused{
    return
}

并将您的按钮更改为:

isPaused.toggle()

Thi should be pretty simple. Keep your timer firing but return in your function if it should pause.

Add this to the start of your .onReceive function:

if isPaused{
    return
}

and change your Button to:

isPaused.toggle()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文