如何强制列表通过另一个视图的切换按钮重绘?
How to force List to redraw by another View's toggle Button?
我从 Google Sheet 中获取了 JSON 数据并使用 ForEach 填充到一个列表中。我使用位于另一个视图中的结构 HeaderView 并放置一个按钮作为切换。但是,即使我使用@State ascd 变量,当我按下切换按钮时,列表也不会重绘。
下面是我的一些代码,有什么我遗漏的吗?
struct HeaderView: View {
// @State var asc: Bool = true
var holding: String = "持倉"
var earning: String = "賺蝕"
// @State var tog_value: Bool = ContentView().ascd
var body: some View {
HStack {
Button(action: {
ContentView().ascd.toggle()
}
) {
Text("Button")
}
Text(holding)
Text(earning)
}
}
}
struct ContentView: View {
@ObservedObject var viewModel = ContentViewModel()
@ObservedObject var viewModelTotal = ContentViewModelTotal()
@State var ascd: Bool = false
var totalss = ContentViewModelTotal.fetchDatasTotal
var body: some View {
List {
Section(header: HeaderView()) {
ForEach(viewModel.rows, id: \.stockname) { rows in
// Text(user.stock_name)
ListRow(name: rows.stockname, code: rows.stockcode, cur_price: rows.currentprice, mkt_value: rows.marketvalue, amnt: rows.amount, avg_cost: rows.averagecost, pft: rows.profit, pft_pcnt: rows.profitpercent)
}
}
.onAppear {
self.viewModel.fetchDatas()
self.ascd.toggle()
if self.ascd {
self.viewModel.rows.sort { [=11=].stockname < .stockname }
} else {
self.viewModel.rows.sort { [=11=].stockname > .stockname }
}
}
}
}
}
要更改另一个视图的变量,您可以使用 @Binding
变量:
struct HeaderView: View {
...
@Binding var ascd: Bool
var body: some View {
HStack {
Button(action: {
self.ascd.toggle()
}) {
Text("Button")
}
Text(holding)
Text(earning)
}
}
}
我建议将排序逻辑移至您的 ViewModel
。
class ContentViewModel: ObservableObject {
@Published var ascd: Bool = false {
didSet {
if ascd {
rows.sort { [=11=].hashValue < .hashValue }
} else {
rows.sort { [=11=].hashValue > .hashValue }
}
}
}
...
}
如果它在ContentView
中的.onAppear
中,它只会在您的View
显示在屏幕上时执行。
并且您必须使用 ViewModel 的 ascd
变量初始化 HeaderView
:
HeaderView(ascd: $viewModel.ascd)
我从 Google Sheet 中获取了 JSON 数据并使用 ForEach 填充到一个列表中。我使用位于另一个视图中的结构 HeaderView 并放置一个按钮作为切换。但是,即使我使用@State ascd 变量,当我按下切换按钮时,列表也不会重绘。
下面是我的一些代码,有什么我遗漏的吗?
struct HeaderView: View {
// @State var asc: Bool = true
var holding: String = "持倉"
var earning: String = "賺蝕"
// @State var tog_value: Bool = ContentView().ascd
var body: some View {
HStack {
Button(action: {
ContentView().ascd.toggle()
}
) {
Text("Button")
}
Text(holding)
Text(earning)
}
}
}
struct ContentView: View {
@ObservedObject var viewModel = ContentViewModel()
@ObservedObject var viewModelTotal = ContentViewModelTotal()
@State var ascd: Bool = false
var totalss = ContentViewModelTotal.fetchDatasTotal
var body: some View {
List {
Section(header: HeaderView()) {
ForEach(viewModel.rows, id: \.stockname) { rows in
// Text(user.stock_name)
ListRow(name: rows.stockname, code: rows.stockcode, cur_price: rows.currentprice, mkt_value: rows.marketvalue, amnt: rows.amount, avg_cost: rows.averagecost, pft: rows.profit, pft_pcnt: rows.profitpercent)
}
}
.onAppear {
self.viewModel.fetchDatas()
self.ascd.toggle()
if self.ascd {
self.viewModel.rows.sort { [=11=].stockname < .stockname }
} else {
self.viewModel.rows.sort { [=11=].stockname > .stockname }
}
}
}
}
}
要更改另一个视图的变量,您可以使用 @Binding
变量:
struct HeaderView: View {
...
@Binding var ascd: Bool
var body: some View {
HStack {
Button(action: {
self.ascd.toggle()
}) {
Text("Button")
}
Text(holding)
Text(earning)
}
}
}
我建议将排序逻辑移至您的 ViewModel
。
class ContentViewModel: ObservableObject {
@Published var ascd: Bool = false {
didSet {
if ascd {
rows.sort { [=11=].hashValue < .hashValue }
} else {
rows.sort { [=11=].hashValue > .hashValue }
}
}
}
...
}
如果它在ContentView
中的.onAppear
中,它只会在您的View
显示在屏幕上时执行。
并且您必须使用 ViewModel 的 ascd
变量初始化 HeaderView
:
HeaderView(ascd: $viewModel.ascd)