SwiftUI ForEach based on State int

大憨熊 提交于 2020-06-07 07:06:46

问题


I am storing a Int value as State in my View. When I press a button the Int increase by one. This is working fine when I print my int value.

I have now a ForEach loop, which iterates based on this Int. When I set my State on 2 by default it works fine at the beginning. However, when I increase that Int my ForEach is not called again.

I understand that State will reload my actual view. Does it only load specific parts?

Here I declare my State:

@State var s_countVenues   : Int = 2

This is the ForEach I use. It works at the beginning, however changing s_countVenues does NOT update the view.

ForEach(0..<self.s_countVenues)
{_ in
    HStack(spacing: 0)
    {
        //here comes my view
    }
}

If necessary, here I am increasing my value by one. It works, I printed the changes and if I use it inside a Label, the Label gets updated.

self.s_countVenues += 1

TL:DR:

My Int State is working. I can increase and print it inside a label. However, using it as Statement in ForEach does not call that loop again after changing.


回答1:


from apple docs

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)
}

So, you have to use (as suggested by 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)")
            })
        }
    }
}



回答2:


It is not due to state, it is because you use ForEach constructor with constant Range, it is documented feature, so not supposed to update, so it is not updated. The simplest solution is as following - to use identifier joined to your state. It just indicates for rendering engine that ForEach is new so refresh (Tested with Xcode 11.2 / iOS 13.2)

ForEach(0..<self.s_countVenues)
{_ in
    HStack(spacing: 0)
    {
        //here comes my view
    }
}.id(s_countVenues)


来源:https://stackoverflow.com/questions/60415844/swiftui-foreach-based-on-state-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!