基于 State int 的 SwiftUI ForEach
Posted
技术标签:
【中文标题】基于 State int 的 SwiftUI ForEach【英文标题】:SwiftUI ForEach based on State int 【发布时间】:2020-02-26 14:12:25 【问题描述】:我将一个 Int 值作为 State 存储在我的视图中。当我按下一个按钮时, Int 增加一。当我打印我的 int 值时,这工作正常。
我现在有一个 ForEach 循环,它基于这个 Int 进行迭代。当我默认将我的状态设置为 2 时,它在一开始就可以正常工作。但是,当我增加 Int 时,我的 ForEach 不会再次被调用。
我了解 State 会重新加载我的实际视图。它只加载特定的部分吗?
我在这里宣布我的国家:
@State var s_countVenues : Int = 2
这是我使用的 ForEach。它在开始时有效,但更改 s_countVenues
不会更新视图。
ForEach(0..<self.s_countVenues)
_ in
HStack(spacing: 0)
//here comes my view
如有必要,我在这里将我的价值加一。它有效,我打印了更改,如果我在标签内使用它,标签就会更新。
self.s_countVenues += 1
TL:DR:
我的 Int 状态正在工作。能在标签里面增加打印。但是,在 ForEach 中将其用作 Statement 并不会在更改后再次调用该循环。
【问题讨论】:
【参考方案1】:来自苹果文档
extension ForEach where Data == Range<Int>, ID == Int, Content : View
/// Creates an instance that computes views on demand over a *constant*
/// range.
///
/// This instance only reads the initial value of `data` and so it does not
/// need to identify views across updates.
///
/// To compute views on demand over a dynamic range use
/// `ForEach(_:id:content:)`.
public init(_ data: Range<Int>, @ViewBuilder content: @escaping (Int) -> Content)
所以,你必须使用(按照 Apple 的建议)
struct ContentView: View
@State var counter = 0
var body: some View
VStack
ForEach(0 ..< counter, id:\.self) i in
Text("row: \(i.description)")
Button(action:
self.counter += 1
, label:
Text("counter \(counter.description)")
)
【讨论】:
@davidev Asperi 的答案有效但不要使用它,直到你不明白它是如何工作的。每次计数器更改时,它都会重新创建 ForEach,这可能是您意想不到的。 好的,谢谢。你的意思是它会再次循环整个 ForEach 吗?你的只是用新的 id 添加最新的? @davidev。非常大致是的。它不存在任何循环,ForEach 是结构,而不是描述循环的快速表达式 简而言之:使用id: \.self
。【参考方案2】:
这不是由于状态,而是因为您使用带有常量Range
的ForEach
构造函数,它是文档化的特性,所以不应该更新,所以它没有更新。最简单的解决方案如下 - 使用加入您的状态的标识符。它只是为渲染引擎表明 ForEach 是新的所以刷新(用 Xcode 11.2 / ios 13.2 测试)
ForEach(0..<self.s_countVenues)
_ in
HStack(spacing: 0)
//here comes my view
.id(s_countVenues)
【讨论】:
再次感谢您的帮助。它工作完美。简短而完美的答案以上是关于基于 State int 的 SwiftUI ForEach的主要内容,如果未能解决你的问题,请参考以下文章