如何通过另一个视图的切换按钮强制列表重绘?

时间:2020-06-03 10:31:39

标签: list swiftui toggle

我从Google表格中获取JSON数据,并使用ForEach填充到列表中。我使用了位于另一个视图中的struct HeaderView,并放置了一个Button来作为切换。但是,即使使用@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 { $0.stockname < $1.stockname }
                } else {
                    self.viewModel.rows.sort { $0.stockname > $1.stockname }
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

要更改另一个View的变量,可以使用@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 { $0.hashValue < $1.hashValue }
            } else {
                rows.sort { $0.hashValue > $1.hashValue }
            }
        }
    }

    ...
}

如果它位于.onAppear的{​​{1}}中,则只有在屏幕上显示ContentView时才会执行。

您将必须使用ViewModel的View变量来初始化HeaderView

ascd