Swiftui Tabview Gives an Error Message During Add/Delete the Element of Coredata

SwiftUI TabView gives an error message during add/delete the element of CoreData

Finally, this problem is solved in Xcode 13 & iOS 15 based!

Full Code

TabView {
ForEach(pages) { page in
SubPage(whichPage: page)
}
}
.tabViewStyle(PageTabViewStyle())

or

TabView {
ForEach(pages) { page in
SubPage(whichPage: page)
}
}
.tabViewStyle(.page)

How can I remove an item from a ForEach inside of a TabView using SwiftUI?

TabView {

ForEach(testViewModel.images, id: \.self) { image in
Image(image)
}

}.tabViewStyle(PageTabViewStyle())
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding()
.frame(width: proxy.size.width, height: proxy.size.height/2.5)
.id(testViewModel.images.count)

Adding an id to the TabView fixes this issue!

SwiftUI holding reference to deleted core data object causing crash

I basically had the same issue. It seems that SwiftUI loads every view immediately, so the view has been loaded with the Properties of the existing CoreData Object. If you delete it within the View where some data is accessed via @ObservedObject, it will crash.

My Workaround:

  1. The Delete Action - postponed, but ended via Notification Center
    Button(action: {
//Send Message that the Item should be deleted
NotificationCenter.default.post(name: .didSelectDeleteDItem, object: nil)

//Navigate to a view where the CoreDate Object isn't made available via a property wrapper
self.presentationMode.wrappedValue.dismiss()
})
{Text("Delete Item")}

You need to define a Notification.name, like:

extension Notification.Name {

static var didSelectDeleteItem: Notification.Name {
return Notification.Name("Delete Item")
}
}

  1. On the appropriate View, lookout for the Delete Message

// Receive Message that the Disease should be deleted
.onReceive(NotificationCenter.default.publisher(for: .didSelectDeleteDisease)) {_ in

//1: Dismiss the View (IF It also contains Data from the Item!!)
self.presentationMode.wrappedValue.dismiss()

//2: Start deleting Disease - AFTER view has been dismissed
DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(1)) {self.dataStorage.deleteDisease(id: self.diseaseDetail.id)}
}


  1. Be safe on your Views where some CoreData elements are accessed - Check for isFault!

VStack{
//Important: Only display text if the disease item is available!!!!
if !diseaseDetail.isFault {
Text (self.diseaseDetail.text)
} else { EmptyView() }
}

A little bit hacky, but this works for me.

TabView with PageTabViewStyle does not update it's content when @State var changes

TabView expects to have container of pages, but you included only one HStack (with own dynamic content), moreover chaining number of pages you have to reset tab view, so here is a fix.

Tested with Xcode 12 / iOS 14

demo

struct ContentView: View {
@State var numberOfPages: Int = 0

var body: some View {
VStack {
Text("Tap Me").onTapGesture(count: 1, perform: {
self.numberOfPages = [2,5,10,15].randomElement()!
})
if self.numberOfPages != 0 {
TabView {
ForEach(0..<numberOfPages, id: \.self) { index in
Text("\(index)").frame(width: 300).background(Color.red)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
.frame(height: 300)
.id(numberOfPages) // << here !!
}
}
}
}

SwiftUI: TabView only works properly without binding (dots don't change)

You just need to add a .tag() to each page, like this:

struct TabViewTest: View {

@State var selected = 0

var body: some View {
TabView(selection: $selected) {
Color.red.edgesIgnoringSafeArea(.all)
.tag(0)

Color.blue.edgesIgnoringSafeArea(.all)
.tag(1)

Color.orange.edgesIgnoringSafeArea(.all)
.tag(2)
}
.tabViewStyle(PageTabViewStyle())
}
}

SwiftUI Core Data error - Cannot convert value of type 'FetchedResultsGCItem' to expected argument type 'RangeInt'

GCItem needs to conform to Identifiable for that code to work. A simple empty conformance should work, as it already has an id:

extension GCItem: Identifiable { }

How to update SwiftUI's ForEach in a TabView with PageTabViewStyle modifier when inserting a new element to the collection at first index

Here is tested workaround for Xcode 12.5 / iOS 14.5.

TabView {
ForEach(myArray, id: \.self) { value in
Text("\(value)")
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.id(myArray.count) // << here !!


Related Topics



Leave a reply



Submit