我对 SwiftUI 还很陌生。 我想制作一个应用程序,可以在导航视图中浏览不同的视图,并在后台运行计时器,在每个视图上显示时间。 问题是当我导航到第二级导航时。当计时器打开时,应用程序会自动返回到之前的导航视图。 这是我的意思的屏幕截图视频: https://youtu.be/eXbK9jpluvk
这是我的代码:
导入 SwiftUI
结构ContentView:视图{
@State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var seconds : Int = 0
@State var paused : Bool = true
var body: some View {
VStack {
Text("\(seconds)")
Button(action: {
paused.toggle()
}) {
Image(systemName: paused ? "play.fill" : "stop.fill")
}
NavigationLink(destination: FirstView( timerSeconds: $seconds, timerPaused: $paused)) {
Text("Navigate 1")
}.padding()
}
.onReceive(self.timer) { currentTime in
if !paused {
seconds = seconds + 1
print(currentTime)
}
}
.navigationViewStyle(.stack)
}
}
结构 FirstView:视图 {
@Binding var timerSeconds : Int
@Binding var timerPaused : Bool
var body: some View {
VStack {
Text("First View")
Text("\(timerSeconds)")
Button(action: {
timerPaused.toggle()
}) {
Image(systemName: timerPaused ? "play.fill" : "stop.fill")
}
NavigationLink(destination: SecondView(seconds: $timerSeconds)) {
Text("Navigate 2")
}
}
}
}
结构 SecondView:视图 {
@Binding var seconds : Int
var body: some View {
Text("\(seconds)")
}
}
欢迎任何帮助! 非常感谢
NavigationView
只能推送一个细节NavigationLink
,因此要获得更多级别,您需要在链接上设置.isDetailLink(false)
。或者,如果您不希望在横向分割视图中运行,您可以在导航上设置 .navigationViewStyle(.stack)
。
就我而言,
.isDetailLink(false)
没有解决问题,但我找到了另一个解决方案。想发帖以防有人寻找类似的案例。
我有一个带有计时器的按钮,可以进行多级导航。为了解决这个问题,我将计时器更新从较高的视图级别移至按钮本身的级别。
struct LinkSentView: View {
@ObservedObject var viewModel: LinkSentViewModel
init(viewModel: LinkSentViewModel) {
self.viewModel = viewModel
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
NavigationLink(destination: nameDestination(), isActive: $viewModel.fakeTrigger) { EmptyView() }
.isDetailLink(false)
ResendTimerButtonView(viewModel: ResendTimerButtonViewModel(resendLinkAction: viewModel.resendLink))
enter code here
}
class ResendTimerButtonViewModel: ObservableObject {
private static let timeLimit = 30
@Published private var timer: Timer?
@Published private var timeRemaining = ResendTimerButtonViewModel.timeLimit
var resendButtonText: String {
timeRemaining > 0 ? "\(timeRemaining)s \(LinkSentView.Constant.resendButtonTitle)" : "\(LinkSentView.Constant.resendButtonTitle)"
}
var resendLinkAction: () -> ()
init(resendLinkAction: @escaping () -> ()) {
self.resendLinkAction = resendLinkAction
}
func startTimer() {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {[weak self] tempTimer in
guard let self = self else { return }
if self.timeRemaining > 0 {
self.timeRemaining -= 1
} else {
tempTimer.invalidate()
}
}
}
func resendLink() {
}
}
struct ResendTimerButtonView: View {
@ObservedObject var viewModel: ResendTimerButtonViewModel
var body: some View {
Button(title: viewModel.resendButtonText, action: {
viewModel.resendLink()
})
.onAppear {
viewModel.startTimer()
}
}
}