Skip to content

Instantly share code, notes, and snippets.

@jeffreybergier
Last active January 22, 2021 00:06
Show Gist options
  • Save jeffreybergier/0a366e173a871c1a8f3828824dbf7a54 to your computer and use it in GitHub Desktop.
Save jeffreybergier/0a366e173a871c1a8f3828824dbf7a54 to your computer and use it in GitHub Desktop.
SwiftUI ObservableCollection Crash
//
//
// SwiftUI.List appears to iterate all the way including the endIndex
// which causes a crash. LazyVStack and ForEach do not do have this issue
//
//
import SwiftUI
@main
struct BoomApp: App {
var body: some Scene {
WindowGroup {
NavigationView {
// Fill the left column of the split view
Color.clear
// Fill the right column
ContentView()
}
}
}
}
struct ContentView: View {
@StateObject var data = ObservableCollection()
var body: some View {
/// LazyVStack and ForEach work fine
/// This appears to be an issue with list
// LazyVStack {
// ForEach(self.data) { boom in
// Text("\(boom.id)")
// }
// }
List(self.data) { boom in
Text("\(boom.id)")
}
.toolbar {
ToolbarItem {
Button("Grow") {
self.data.grow()
}
}
ToolbarItem {
Button("Shrink") {
// This causes a crash
self.data.shrink()
}
}
}
}
}
struct Boom: Hashable, Identifiable {
var id: Int
init(_ id: Int) {
self.id = id
}
}
class ObservableCollection: RandomAccessCollection, ObservableObject {
func grow() {
self.objectWillChange.send()
self.endIndex += 1
}
func shrink() {
guard self.endIndex > self.startIndex else { return }
self.objectWillChange.send()
self.endIndex -= 1
}
typealias Index = Int
typealias Element = Boom
var startIndex: Index = 0
var endIndex: Index = 0
subscript(index: Index) -> Iterator.Element {
guard index < self.endIndex else { fatalError("Index Out of Bounds") }
return Boom(index)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment