基于 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】:

这不是由于状态,而是因为您使用带有常量RangeForEach 构造函数,它是文档化的特性,所以不应该更新,所以它没有更新。最简单的解决方案如下 - 使用加入您的状态的标识符。它只是为渲染引擎表明 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的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 基于计算属性显示警报

SwiftUI:自定义SearchBar

SwiftUI - 如何创建全局 @State 变量?

SwiftUI - 更新@State 不会改变视图

SwiftUI,为啥部分视图没有刷新? @State 变量未更新

为 Swiftui 视图转换 @State 的计算属性