如何正确处理更新视图中的选取器(SwiftUI)

Posted

技术标签:

【中文标题】如何正确处理更新视图中的选取器(SwiftUI)【英文标题】:How to correctly handle Picker in Update Views (SwiftUI) 【发布时间】:2021-02-26 19:31:09 【问题描述】:

我对 SwiftUI 很陌生,我想知道如何在更新视图中正确使用选择器。

目前我有一个表单并使用.onAppear() 加载数据。这很好,但是当我尝试选择一些东西并返回更新视图时,.onAppear() 再次被调用,我失去了选择的值。

在代码中是这样的:

import SwiftUI

struct MaterialUpdateView: View 
    
    // Bindings
    @State var material: Material
    
    // Form Values
    @State var selectedUnit = ""
    
    var body: some View 

        VStack()
            List() 
                Section(header: Text("MATERIAL"))

                    // Picker for the Unit
                    Picker(selection: $selectedUnit, label: Text("Einheit")) 
                        ForEach(API().units)  unit in
                            Text("\(unit.name)").tag(unit.name)
                        
                    

                
            
            .listStyle(GroupedListStyle())
            
        
        .onAppear()
            prepareToUpdate()
        
    

    func prepareToUpdate() 
        self.selectedUnit = self.material.unit
    


有没有人遇到过这个问题或者我做错了什么?

【问题讨论】:

使用 init 或搜索 SwiftUI + 视图确实加载了。 感谢您的提示。你能给我举个例子吗?我不知道如何使用它。 @RajaKishan 你可以试试 .onAppear() guard !selectedUnit.isEmpty else return prepareToUpdate() 检查这个答案:***.com/a/64495887/14733292 【参考方案1】:

您需要创建一个custom binding,我们将在另一个子视图中实现它。该子视图将使用绑定变量selectedUnitmaterial 进行初始化

首先,让你的MaterialUpdateView

struct MaterialUpdateView: View 
    
    
    // Bindings
    @State var material : Material
    
    // Form Values
    @State var selectedUnit = ""
    
    
    var body: some View 
        
        NavigationView 
            
            VStack()
                List() 
                    Section(header: Text("MATERIAL")) 
                        
                        MaterialPickerView(selectedUnit: $selectedUnit, material: $material)
                        
                    
                    .listStyle(GroupedListStyle())
                
                .onAppear()
                    prepareToUpdate()
                    
                
                
            
        
        
    
    
    func prepareToUpdate() 
        self.selectedUnit = self.material.unit
    
    

然后,在下面添加您的MaterialPickerView,如图所示:

免责声明:您需要能够从此处访问您的API(),因此请将其移动或添加到此视图中。正如我所看到的,您每次都在重新实例化它,也许最好用let api = API() 存储它的实例,然后用api 引用它,甚至将它传递给这个视图!

struct MaterialPickerView: View 
    
    @Binding var selectedUnit: String
    @Binding var material : Material
    @State var idx: Int = 0
        
    var body: some View 
        
        let binding = Binding<Int>(
            get:  self.idx ,
            set: 
                self.idx = $0
                self.selectedUnit = API().units[self.idx].name
                self.material.unit = self.selectedUnit
            )
        
        return Picker(selection: binding, label: Text("Einheit")) 
            ForEach(API().units.indices)  i in
                Text(API().units[i].name).tag(API().units[i].name)
            
        
    

应该可以,如果有效,请告诉我!

【讨论】:

以上是关于如何正确处理更新视图中的选取器(SwiftUI)的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:列表项跳转到选取器表单中的标题

SwiftUI:将选取器选择设置为动态数组中的最后一个

SwiftUI 无法删除选取器上方的空间 - 表单版本

SwiftUI:设置选取器行高

SwiftUI 2 .onChange() 中的选取器不会更改 UINavigationBar.appearance()

SwiftUI 自定义选取器标签未呈现