微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

滚动列表中的项目时丢弃 SwiftUI 状态

如何解决滚动列表中的项目时丢弃 SwiftUI 状态

我对 Swift 和 SwiftUI 非常陌生,因此对于这个非常基本的问题深表歉意。我一定误解了 SwiftUI 生命周期以及它与 @State 的交互。

我有一个列表,当您单击该行时,它会增加一个计数器。如果我点击一些行项目来增加计数器,向下滚动,然后再次向上滚动 - 状态再次重置为 0。谁能指出我哪里出错了?非常感谢。

struct TestView : View {
    @State private var listItems:[String] = (0..<50).map { String($0) }
    var body: some View {
        List(listItems,id: \.self) { listItem in
            TestViewRow(item: listItem)
        }
    }
}

struct TestViewRow: View {
    var item: String
    @State private var count = 0
    
    var body: some View {
        HStack {
            Button(item,action: {
                self.count += 1
            })
            Text(String(self.count))
            Spacer()
        }
    }
}

解决方法

List 中的项目可能延迟加载,具体取决于操作系统(macOS 与 iOS)、列表长度、屏幕上的项目数量等。 >

如果加载了一个列表项,然后它的状态发生了变化,并且该项自卸载/重新加载到 List 中后,则不会将该状态重新分配给该项。

不是在每个 @State 行上存储 List,您可以将状态移动到不会被卸载的父视图:

struct ContentView : View {
    @State private var listItems:[(item:String,count:Int)] = (0..<50).map { (item:String($0),count:0) }
    
    var body: some View {
        List(Array(listItems.enumerated()),id: \.0) { (index,item) in
            TestViewRow(item: item.item,count: $listItems[index].count)
        }
    }
}

struct TestViewRow: View {
    var item: String
    @Binding var count : Int
    
    var body: some View {
        HStack {
            Button(item,action: {
                count += 1
            })
            Text(String(count))
            Spacer()
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。