从 SwiftUI 列表中的每个元素获取用户输入

Posted

技术标签:

【中文标题】从 SwiftUI 列表中的每个元素获取用户输入【英文标题】:Taking input from a user per element in a SwiftUI List 【发布时间】:2020-06-28 17:57:18 【问题描述】:

我在制作 SwiftUI 视图列表以从用户那里获取数值时遇到了问题。

列表中的每个元素都是一个表示问题结构的视图,并且应该取回一个 int 值。首先,我尝试将值直接放在视图结构上,因为问题结构本身显然不应该包含任何答案。计划是将视图的答案与问题的 id 和时间戳结合起来,然后存储在其他地方。

struct QuestionRow: View 
    var question: Question
    @State var trueRating: Int = -1
    @State var displayedRating: Int = -1

这失败了,因为 SwiftUI 的 List 在进入和离开屏幕时动态生成并丢弃视图(或者至少我认为这是问题所在,Apple 对此的文档似乎很少)。从而在用户浏览列表时破坏我的数据。

对此的解决方案似乎是为答案引入一个结构(无论如何我最终都会这样做)。用户将与视图交互,这会将数据保存到新结构中;即使列表卸载了数据也会被保留。

struct AnswerRow: View 
    var answer: Answer

这直接导致了

Cannot use mutating member on immutable value: 'self' is immutable

因为它当然做到了。不能在标记为“mutating”的函数之外修改视图结构的成员,而视图结构体声明不是。

我可以想到两种解决方法:

    在视图结构中创建一个包装函数
mutating func SetScoreWrapper(score: Int) 
        self.answer.SetScore(newScore: score)
    
    把我的结构变成一个类?

有些事情告诉我有更好的方法来解决这个问题。 你怎么看?

【问题讨论】:

【参考方案1】:

如果您没有很多问题并且想要保留问题的状态,那么您可以使用VstackForEach 来构建每个QuestionRow。请注意,这将导致它们在视图出现时全部加载到内存中,因此如果您有数百行,这不是一个好的选择。

如果您想坚持使用List,请尝试创建Answers 数据模型,并使其在带有列表的视图中成为有状态的。然后,您可以将绑定传递给每个QuestionRow,这将更新事实来源。这可以防止当行滚动到屏幕外时信息被破坏。

【讨论】:

以上是关于从 SwiftUI 列表中的每个元素获取用户输入的主要内容,如果未能解决你的问题,请参考以下文章

从 SwiftUI 的列表中删除列表元素

SwiftUI 和 Core Data:基于用户输入获取

如何从 SwiftUI 中的列表中获取屏幕行?

如何从firestore中检索swiftUI中的预定义项目列表?

在不使用导航链接的情况下获取 SwiftUI 列表中的选定项目

SwiftUI:动画列表中的圆圈