我是 SwiftUI 的新手,正在尝试开发我的第一个应用程序。我正在尝试使用分段选择器为用户提供在 DayView 和 Week View 之间切换的选项。在这些 View 中的每一个中,都会有特定的用户数据显示为图表。我遇到的问题是加载数据。我在下面发布了代码,但据我所知,问题归结为以下几点:
当加载 View 时,它首先加载 dayView,因为 selectedTimeInterval = 0。这很好,但是当用户按下分段选择器中的“周”时,数据不显示。这是由于在分段选择器运行的 .onChange() 函数之前加载其余 View 。由于 .onChange 将调用放入 viewModel 以加载新数据,因此没有数据。如果您运行下面的代码,您可以在打印语句中看到这一点。
我本以为 View 加载顺序会是
加载分段选择器 如果值更改,则运行 .onChange 加载 View 的其余部分 但实际订单是
加载分段选择器, 加载 View 的其余部分(图表加载此处没有数据!!!!!!) 如果值已更改,则运行 .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
用于 View 的本地状态。这个想法是你用初始状态初始化它,从那时起 View 本身将改变它并导致重新渲染。重新渲染 WeekView 时,SwiftUI 会忽略您传递给 init 的参数,并从之前的 WeekView 复制它以保持状态。
但是,您希望继续从 ContentView 传入字典并导致从父 View 重新呈现。
关于swift - SwiftUI 分段选择器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73839152/