iOS 15 SwiftUI 3 Picker 绑定在更改@State 值后不起作用

Posted

技术标签:

【中文标题】iOS 15 SwiftUI 3 Picker 绑定在更改@State 值后不起作用【英文标题】:iOS 15 SwiftUI 3 Picker binding is not working after changing @State value 【发布时间】:2021-10-05 03:36:54 【问题描述】:

我正在尝试使用来自 SwiftUI 的 Picker,我让此代码适用于 ios 14,但是当我更新项目以使用 iOS 15 时,它现在已损坏,并且在分配 @State 后,Picker 不再更新视图出现。

我从零开始创建了一个新项目来测试它,是的,我可以复制错误。

这是我正在使用的代码:

import SwiftUI

struct Category: Identifiable 
    let id: UUID = UUID()
    let name: String


let categories: [Category] = [
    Category(name: "Cat 1"),
    Category(name: "Cat 2"),
    Category(name: "Cat 3")
]

struct ContentView: View 
    
    @State private var selectedCategory = -1
    
    var body: some View 
        NavigationView 
            Form 
                Section 
                    Picker("Category", selection: $selectedCategory) 
                        ForEach(0..<categories.count) 
                            Text(categories[$0].name)
                                .tag($0)
                        
                    
                
            
            .onAppear 
                self.selectedCategory = 1
            
        
    


正如您在 onAppear 块中看到的,我正在更改 selectedCategory 值,这种代码和平在 iOS 14 中运行良好,但在 iOS 15 中运行良好。

谢谢

【问题讨论】:

适用于 Xcode 13 / iOS 15。 @Asperi 你能改变和选择一个不同的类别吗? 【参考方案1】:

似乎 iOS 15 无法像以前那样更改 State var 的值并将其作为绑定发送到 Picker。

问题是 State var selectedCategory 作为绑定发送到 Picker 并且当我尝试在出现视图时更改 selectedCategory var 的值时,绑定没有被更新并且 Picker 值在您选择不同的类别。

我所做的是在初始化 Picker 之前更改 init 函数中的 selectedCategory 值:

import SwiftUI

struct Category: Identifiable 
    let id: UUID = UUID()
    let name: String


let categories: [Category] = [
    Category(name: "Cat 1"),
    Category(name: "Cat 2"),
    Category(name: "Cat 3")
]

struct ContentView: View 
    
    @State private var selectedCategory = -1
    
    init() 
        self._selectedCategory = State(initialValue: 1)
    
    
    var body: some View 
        NavigationView 
            Form 
                Section 
                    Picker("Category", selection: $selectedCategory) 
                        ForEach(0..<categories.count) 
                            Text(categories[$0].name)
                                .tag($0)
                        
                    
                
            
        
    

为什么我需要在 init 上赋值? 这是因为在我的项目中,我需要更新核心数据记录,并将记录作为ObservedObject 发送到视图并更改类别,我需要更改selectedCategory 以获得核心数据记录的值而不是默认值,通过更改 onAppear 中的值,选择器会损坏并且不再工作,因此在 iOS 15 中执行此操作的最佳方法是在 init 函数中设置值,而不是在 onAppear 中设置值。

【讨论】:

【参考方案2】:

从 onAppear 中删除 self.selectedCategory = 1 ,它会正常工作。

struct ContentView: View 

    @State private var selectedCategory = 1

        var body: some View 
            NavigationView 
                Form 
                    Section 
                        Picker("Category", selection: $selectedCategory) 
                            ForEach(0..<categories.count) 
                                Text(categories[$0].name)
                                    .tag($0)
                            
                        
                    
                
                .onAppear 
//                    self.selectedCategory = 1
                
        
            
        

你可以在声明的时候直接设置默认值

@State private var selectedCategory = 1 //this will set your default value

【讨论】:

我需要在视图出现时更改值

以上是关于iOS 15 SwiftUI 3 Picker 绑定在更改@State 值后不起作用的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI Picker 从 CoreData 返回空字符串

SwiftUI Picker 手动触发扩展

iOS 15.3.1中SwiftUI toolbar中按钮不响应点击动作等若干不兼容问题的解决

iOS 15.3.1中SwiftUI toolbar中按钮不响应点击动作等若干不兼容问题的解决

SwiftUI 中的一排 Picker ***,为啥拖动滚动区域从屏幕上的 Picker 控件偏移?

iOS 15 中的 Swift 和 SwiftUI