DEV Community

Jaakko Kangasharju
Jaakko Kangasharju

Posted on

2 3

I had a bug with ForEach and Range in my SwiftUI code

I have a side project for iOS, and since it's a side project, I thought to try SwiftUI for the UI. There's some complexity because the UI isn't exactly traditional, but overall, I've been happy with SwiftUI.

But when Xcode 11.4 was released, the app wouldn't work properly. Some, but not all, parts of the UI weren't updating anymore when state changed. For a while, I stayed on 11.3 so I could work on the functionality, but as time passed, it became evident that this wasn't a problem with Xcode or iOS, it was something in my code.

Mostly, I thought that I had messed up with the bindings so that the UI wasn't observing my presentation layer properly. No luck there, nothing I tried would work. After a lot of frantic Web searching, I eventually found the answer in the comments to an unrelated blog post.

My code looked something like this

struct MainView: View {
  @Binding var names: [[String?]]

  var body: some View {
    VStack {
      ForEach(0..<self.names.count) { nameIndex in
        NamesView(self.$names[nameIndex])
      }
    }
  }
}

The problem is that ForEach has three init methods,

init(Data, content: (Data.Element) -> Content)
init(Range<Int>, content: (Int) -> Content)
init(Data, id: KeyPath<Data.Element, ID>, content: (Data.Element) -> Content)

and using it like I did picks the second one, with the Range parameter. This method assumes that the range doesn't change, which is true in my case, but it also seems to assume that the content views don't change, at least from Xcode 11.4 onward. Maybe this is a bug, maybe it's intended behavior, I can't tell from the documentation.

When I had finally discovered the problem, the fix was simple enough. I changed the ForEach to

      ForEach(0..<self.names.count, id: \.self) { nameIndex in
        NamesView(self.$names[nameIndex])
      }

which picks the third init method of ForEach, and allows updates of the views.

Jetbrains image

Is Your CI/CD Server a Prime Target for Attack?

57% of organizations have suffered from a security incident related to DevOps toolchain exposures. It makes sense—CI/CD servers have access to source code, a highly valuable asset. Is yours secure? Check out nine practical tips to protect your CI/CD.

Learn more

Top comments (1)

Collapse
 
rabblerousy profile image
RabbleRousy

I created an account just to say THANK YOU!!!! I had exactly the same problem, what a stupidly easy fix. I hate SwiftUI for making solutions like this so hard to find ...

AI Agent image

How to Build an AI Agent with Semantic Kernel (and More!)

Join Developer Advocate Luce Carter for a hands-on tutorial on building an AI-powered dinner recommendation agent. Discover how to integrate Microsoft Semantic Kernel, MongoDB Atlas, C#, and OpenAI for ingredient checks and smart restaurant suggestions.

Watch the video 📺

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay