I have a carousel and each carousel item contains a unique tableview. When you tap the add button it takes you to a new view controller so that you can give the tableview a name and associate items to display in each cell. Now when I hit the save button it performs the segue back to the carousel's viewcontroller. My prepareforsegue
looks like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! BillSplittersViewController
let passedBill: NSManagedObject = bill as NSManagedObject
destinationVC.allBillSplitters = getUpdatedSplitters()
print(2)
print(destinationVC.allBillSplitters)
destinationVC.billName = billName
destinationVC.bill = passedBill
}
When the carousel view controller is displayed it doesn't show the added item in the carousel which loads from the allBillSplitters
array. If I try reloading the carousel in viewdidload
, viewwillappear
or view willlayoutsubviews
nothing changes. It does update if I do it in viewdidlayoutsubviews
but you can see this happening which isn't great.
To debug I tried printing the array in prepareforsegue
and then in viewdidload
and it prints the array in prepareforsegue
without the added item and the does the same thing in viewdidload
-- but then it prints them again with the added item -- but I can't see it in the loaded view.
I'm using iCarousel if that helps. I am new to this and unsure what's going on so I don't know what code to use. I am using storyboards for both viewcontrollers and the segue is attached to the view and not the button itself. Any help would be great. Thanks!
More information:
@IBAction func saveButtonWasPressed() {
let managedContext = bill.managedObjectContext
if let splitter = splitter {
splitter.mutableSetValue(forKey: "items").removeAllObjects()
setBillSplitterValues(splitter)
setSelectedItemsToBillSplitter(splitter)
} else {
let entity = NSEntityDescription.entity(forEntityName: "BillSplitter", in: managedContext!)
let newBillSplitter = NSManagedObject(entity: entity!, insertInto: managedContext)
setBillSplitterValues(newBillSplitter)
setSelectedItemsToBillSplitter(newBillSplitter)
}
do {
try managedContext!.save()
}
catch let error as NSError {
print("Core Data save failed: \(error)")
}
self.performSegue(withIdentifier: "segueToBillSplitters", sender: self)
}
retrieving the new billSplitters:
func getUpdatedSplitters() -> [BillSplitter] {
var allBillSplitters = [BillSplitter]()
let managedContext = bill.managedObjectContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "BillSplitter")
let predicate = NSPredicate(format: "ANY bills == %@", bill)
fetchRequest.predicate = predicate
do {
let results =
try managedContext!.fetch(fetchRequest)
allBillSplitters = results as! [BillSplitter]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
return allBillSplitters
}
So when pressing save, it either updates an existing 'billSplitter' to coredata or adds a new one, then calls performSegue
. In prepareForSegue
it then fetches all the 'billSplitters' from CoreData and passes them to the destination view controller.
I thought a NSManagedObjectContextDidSave
observer might help if it called performSegue
once the notification was received but nothing changed.
Update:
I have tried the following in my saveButtonWasPressed
method. When the viewcontroller loads, it quickly shows the old carousel then flickers and shows the updated carousel. I'm not sure where to go from here.
@IBAction func saveButtonWasPressed() {
DispatchQueue.global(qos: .background).async { [weak weakSelf = self] in
let managedContext = weakSelf?.bill.managedObjectContext
if let splitter = weakSelf?.splitter {
splitter.mutableSetValue(forKey: "items").removeAllObjects()
weakSelf?.setBillSplitterValues(splitter)
weakSelf?.setSelectedItemsToBillSplitter(splitter)
} else {
let entity = NSEntityDescription.entity(forEntityName: "BillSplitter", in: managedContext!)
let newBillSplitter = NSManagedObject(entity: entity!, insertInto: managedContext)
weakSelf?.setBillSplitterValues(newBillSplitter)
weakSelf?.setSelectedItemsToBillSplitter(newBillSplitter)
}
do {
try managedContext!.save()
}
catch let error as NSError {
print("Core Data save failed: \(error)")
}
DispatchQueue.main.async { [weak weakSelf = self] in
guard let weakSelf = weakSelf else { return }
weakSelf.performSegue(withIdentifier: "segueToBillSplitters", sender: self)
}
}
}