我对SwiftUI还比较陌生,我正在尝试开发我的第一个应用程序。我正在尝试使用分段选取器,为用户提供在DayView和Week View之间切换的选项。在这些视图中的每一个视图中,都会有特定的用户数据显示为图形。我遇到的问题是加载数据。我在下面发布了代码,但从我所看到的,问题归结为以下几点:
加载视图时,会从加载dayView开始,因为selectedTimeInterval=0。这很好,但当用户按下";"周";在分段选取器中,数据不显示。这是由于在分段选取器运行.onChange((函数之前加载视图的其余部分。由于.onChange将调用放入viewModel以加载新数据,因此没有数据。如果运行下面的代码,您可以在print语句中看到这一点。
我本以为视图加载顺序会是
装载分段拾取器如果值已更改,请运行.onChange加载视图的其余部分但实际订单是
装载分段拾取器,加载视图的其余部分(图加载时此处没有数据!!!!(如果值已更改,请运行.onChange。我很失落,所以任何帮助都会很棒!非常感谢!
import SwiftUI
import OrderedCollections
class ViewModel: ObservableObject{
@Published var testDictionary: OrderedDictionary<String, Int> = ["":0]
public func daySelected() {
testDictionary = ["Day View Data": 100]
}
public func weekSelected() {
testDictionary = ["Week View Data": 200]
}
}
struct ContentView: View {
@State private var selectedTimeInterval = 0
@StateObject private var vm = ViewModel()
var body: some View {
VStack {
Picker("Selected Date", selection: $selectedTimeInterval) {
Text("Day").tag(0)
Text("Week").tag(1)
}
.pickerStyle(SegmentedPickerStyle())
.onChange(of: selectedTimeInterval) { _ in
let _ = print("In on change")
//Logic to handle different presses of the selector
switch selectedTimeInterval {
case 0:
vm.daySelected()
case 1:
vm.weekSelected()
default:
print("Unknown Selected Case")
}
}
switch selectedTimeInterval {
case 0:
let _ = print("In view change")
Day_View()
case 1:
let _ = print("In view change")
Week_View(inputDictionary: vm.testDictionary)
default:
Text("Whoops")
}
}
}
}
struct Day_View: View {
var body: some View {
Text("Day View!")
}
}
struct Week_View: View {
@State private var inputDictionary: OrderedDictionary<String,Int>
init(inputDictionary: OrderedDictionary<String,Int>) {
self.inputDictionary = inputDictionary
}
var body: some View {
let keys = Array(inputDictionary.keys)
let values = Array(inputDictionary.values)
VStack {
Text(keys[0])
Text(String(values[0]))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
在您的WeekView中,更改
@State private var inputDictionary: OrderedDictionary<String,Int>
至
private let inputDictionary: OrderedDictionary<String,Int>
@State
表示视图的本地状态。这个想法是,你用初始状态初始化它,从那时起,视图本身将改变它并导致重新渲染。重新渲染WeekView时,SwiftUI将忽略传递到init中的参数,并将其从上一个WeekView中复制以保持状态。
但是,您希望继续从ContentView传入字典,并导致从父视图重新渲染。
主要问题是@State
属性包装器的初始化错误。
您必须使用此语法
@State private var inputDictionary: OrderedDictionary<String,Int>
init(inputDictionary: OrderedDictionary<String,Int>) {
_inputDictionary = State(wrappedValue: inputDictionary)
}
或者,如果不修改inputDictionary
,只需将其声明为(非私有(常量并删除init
方法
let inputDictionary: OrderedDictionary<String,Int>