swift - 一个swiftUI问题:应用状态属性的麻烦
问题描述
我正在尝试使用需要计时器的 SwiftUI 构建提醒。
我的问题是,由于缺少 State 变量,时间变量(包括小时、分钟和秒)无法在 GUI 上更新。
而在我的情况下,我不知道如何将绑定变量times
(首先通过确保它是两位数字符串的方法)转换为状态变量。body 变量不允许我在里面做,我也不能在外面使用绑定变量和函数。我应该怎么办?
import SwiftUI
struct PresentView: View {
@Binding var times: DataStorage
@State private var hourOut = "" // Stuck at here
@State private var AlertPresent = false
@State private var timerRun = false
let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()
func DigitPresent(time: Int) -> String {
guard time > 9 else {
return "0\(String(time))"
}
return String(time)
}
var body: some View {
VStack {
Text("\(DigitPresent(time: times.hour)) : \(DigitPresent(time: times.minute)) : \(DigitPresent(time: times.second))")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.bottom)
.onReceive(timer, perform: { _ in
if (timerRun == true) {
if (times.second > 0) {
times.second -= 1
} else if (times.minute > 0) {
times.minute += 59
times.minute -= 1
} else if (times.hour > 0) {
times.minute += 59
times.second += 59
times.hour -= 1
} else {
AlertPresent = true
timer.upstream.connect().cancel()
}
}
})
.alert(isPresented: $AlertPresent, content: {
Alert(title: Text("Time over"), message: nil, dismissButton: .default(Text("OK"), action: {
AlertPresent = false
}))
})
Button(action: {
timerRun = true
}, label: {
Text("Start/Stop")
})
}
}
}
struct PresentView_Previews: PreviewProvider {
static var previews: some View {
PresentView(times: .constant(DataStorage.data[0]))
}
}
现在我正在尝试将 EnvironmentObject 应用到这个视图中。虽然问题是,还有其他使用绑定属性变量的视图使用 NavigationView 链接到此视图,这会导致错误数据类型的错误:
struct SetView: View {
@Binding var cards: [DataStorage]
@State private var sheetPresent = false
@State private var newReminder = DataStorage.dataOutput()
var body: some View {
List {
ForEach (cards) { card in
NavigationLink(destination: PresentView(times: connect(to: card))) {
CardView(info: card)
}
.listRowBackground(card.color)
}
}
.navigationTitle("information")
.navigationBarItems(trailing: Button(action: {
sheetPresent = true
}, label: {
Image(systemName: "plus")
}))
.sheet(isPresented: $sheetPresent, content: {
NavigationView {
EditView(storedData: $newReminder)
.navigationBarItems(leading: Button("Delete", action: {
sheetPresent = false
}), trailing: Button("Add", action: {
let information = DataStorage(title: newReminder.title, hour: newReminder.hour, minute: newReminder.minute, second: newReminder.second, color: newReminder.color)
cards.append(information)
sheetPresent = false
}))
}
})
}
private func connect (to card: DataStorage) -> EnvironmentObject<DataStorage> {
guard let cardNumber = cards.firstIndex(where: {$0.id == card.id}) else {
fatalError("Can't find card")
}
return $cards[cardNumber] // The error starts here
}
}
我应该怎么办?修复连接功能或更改“卡片”变量的属性?
解决方案
我看不到您的 DataStorage 变量,但我会说使其成为符合@ObservableObject 的类,然后将@Published 应用于小时、分钟、秒。
然后将时间声明为 @ObservedObject 而不是 @Binding 。
我还将您在 onReceive 中的逻辑移动到 DataStorage - 您的视图应该只关心告诉它更新,而不是如何更新。
推荐阅读
- sql - 如何制定一个允许用户从今天起只输入 DateTime 的 CHECK 约束?
- c++ - 在这个例子中,指针的指针做什么?
- django - 嵌套序列化程序中的媒体 URL 不完整
- javascript - 在 React Native Firebase 中重新加载应用程序后无法更新状态?
- jenkins - 如何修复詹金斯管道中的 JNLPLauncher 异常
- python - 始终在 Google Cloud 上运行 Python 脚本
- php - 具有适当权限的现有文件路径的 Nginx“没有此类文件或目录错误”
- python - 如何根据 numpy 数据类型确定 PostgreSQL 列数据类型?
- javascript - 如何实现 React 路由?
- postgresql - 如何选择最近的记录,然后根据其值进行查询?