0

I have an array of structs, which ForEach uses to generate SubViews. When I delete one of object from that array, one of SubViews disappear as expected. But when I pass an EnvironmentObject to the SubView and that view gets deleted, app crashes. By the way, its a Mac App.

import SwiftUI

struct Item: Identifiable {
    var id = UUID().uuidString
    var title: String
}

class Data: ObservableObject {
    @Published var items: [Item] = [Item(title: "One"), Item(title: "Two"), Item(title: "Three")]
    
    func removeOneItem (){
        if items.count > 0 {
            items.remove(at: 0)
        }
    }
}

struct ContentView: View {
    @StateObject var data = Data()
    var body: some View {
        VStack {
            ForEach(data.items.indices, id:\.hashValue) { i in
                SubView(item: $data.items[i]).environmentObject(data)
            }
            Button(action: data.removeOneItem) {Text("Remove one item").foregroundColor(.red)}
        }
    }
}

struct SubView: View {
    @Binding var item: Item
    @EnvironmentObject var data: Data  // <- works only without this line
    var body: some View {
        Button { self.item.title = "tapped"} label: {Text(item.title)}
    }
}

Any ideas?

Jayåk
  • 9
  • 6
  • Xcode crash message: Swift/ContiguousArrayBuffer.swift:580: Fatal error: Index out of range – Jayåk Sep 28 '21 at 12:07
  • Hey Jayåk, looks like you have some real system issues with your setup. Your code works well for me on macos 12.beta7, xcode 13.beta5 (not release), target macos 12. Maybe it is different on older systems. You can also "attach" the `.environmentObject(data)` to the `VStack {...}.environmentObject(data)` – workingdog support Ukraine Sep 28 '21 at 12:34
  • You should watch Demystify SwiftUI from WWDC2021 the way your loop is setup is unsafe and likely the source of your crash – lorem ipsum Sep 28 '21 at 12:34
  • One other issue, `Data()` is already a type in swift. You should not be implementing `class Data: ObservableObject`. – Yrb Sep 28 '21 at 12:35
  • Hmm... what is `SubView` doing with `data`? Does it need to alter it? There will be a better way of doing this but it depends on what it's doing with `data`. Can you update your code sample for `SubView` to show it actually using `data`. – Fogmeister Sep 28 '21 at 12:37
  • @Yrb that's true although in Swift not as much of an issue as it used to be as each type will be namespaced into where it is created. To refer to the `Data` you are referencing you would need to use `Swift.Data` instead. It works, but yeah, not ideal :D – Fogmeister Sep 28 '21 at 12:38
  • @Fogmeister, I can print/manipulate the `data.items` in `SubView` without any problem. – workingdog support Ukraine Sep 28 '21 at 12:41
  • @workingdog Looks like it! Im on Big Sur, gotta install Monterey I guess. – Jayåk Sep 28 '21 at 12:43
  • @Yrb Thanks! I called it Data just in this sample. In my project it has different Name. Thanks for noticing it! – Jayåk Sep 28 '21 at 12:44
  • works for me on Monterey, be sure to use Xcode 13-beta5, not release. Xcode release only targets macOS Big Sur 11.3. You will not get all the good SwiftUI 3.0 with that. – workingdog support Ukraine Sep 28 '21 at 12:46
  • @loremipsum Thanks! The thing is I couldn't find any other way to bind separate item to View. Tried putting $data.items into ForEach, but it only worked for iOS, but not for Mac. – Jayåk Sep 28 '21 at 13:18
  • @workingdog Maybe that is the reason.. Literally last night Xcode got updated automatically so I thought it was destiny and 諦めた the 12th version. – Jayåk Sep 28 '21 at 13:20
  • @Fogmeister You see this Data class has some common vars, such as "selectedView" so I it would be accessible for each SubView to set itself as active. – Jayåk Sep 28 '21 at 13:23
  • That NP. That setup may work once Monterrey is available in RC or on the AppStore version of Xcode. Basically once Swift5.5 becomes available for Mac. The only way to test it would be with Monterrey and Beta Xcode. It should be backwards compatible once the sdk is in a public release. – lorem ipsum Sep 28 '21 at 13:29
  • you can download Xcode 13-beta5 from the Apple Developer site. Don't click on the "Beta", click on the "More" at the top right corner to get the betas, obviously! – workingdog support Ukraine Sep 28 '21 at 13:51

0 Answers0