Considering I have a array of items which might be updated on a different view controller and get notified update the change.
How can I update a Observable<[SomeObject]> with a single SomeObject modification so the change will then be propagated to the UITableViewController that presets these items?
P.S.
I can load the whole thing again with some hack, but it's obviously wrong for various reasons.
Thanks.
The short answer is, you can't.
However, if you change your model, there are several ways you can go about doing it. One example is here: https://github.com/dtartaglia/RxMultiCounter
In RxMultiCounter, I populate the tableView with an Observable<[UUID]> and track the changes for each item inside an Observable<[UUID: SomeObject]>. Updating the latter observable doesn't cause the tableView to reload.
Related
No, my code is not crashing by just deleting content, or reordering content, that works fine.
The issue is, the content is connected to a pusher service and it might need to delete a row at any point, even while reordering. I have been looking around for some time and I haven't found a way to:
Cancel the reordering of the cell when delete is needed (it goes
blank / clear).
Avoid any actions from a deleted cell when it finishes
'reordering'.
Tell if the table is reordering the cell before I need to
delete it.
So in short I need to delete a cell that might be reordering from a UITableView.
Have you faced a similar issue?
Anyways, I found a way to do it. Here's the logic just in case anyone ever needs it.
Prevent the cell's movement with the use of tableView:targetIndexPathForMoveFromRowAt:
On delete control don't call [yourTableView].deleteRows, call reloadData
Looks like that's it.
Thanks
I'm currently developing and iOS app in Swift 2.0 and I'm running into the following issue:
I have a custom query that fetches a list of items that populate a UITableView. When tapping the cell I get the ( values[indexPath.row] ) Object and segue it to another view controller for display as well as the list of items (for other actions like swipe to move to the next one).
My issue comes from a background process that fetches periodically new data and saves it to Realm.
Since Realm keeps all nice and updated, the indexPath.row will fetch a different value (the list of values has changed in the meantime due to the automatic updater) resulting in showing something that is not quite what was tapped.
Both Realm and the updater are working, but this results in a confusing experience for the user.
Am I missing something obvious?
Thanks a lot for the help!
PS: I've looked also at ABFRealmTableViewController, but I'm not displaying the whole data but a filtered (and ordered) subset.
Probably the easiest way of preventing this issue is to observe notifications sent out by Realm whenever a write transaction (i.e. an update) occurs and update your UI accordingly:
// Observe Realm Notifications
let token = realm.addNotificationBlock { notification, realm in
viewController.updateUI()
}
ABFRealmTableViewController supports filters via NSPredicate and sort descriptors as well. So you might want to give it another try.
I implemented a modified view for my data using the filters, which only shows the modified items. And I have auto-saving feature. The issue is that when users edit data in the modified view, my auto-save method will override the original data with the ones in my modified view.
Is there a way to get all items from a TreeStore other than removing its filters? (I can surely remove the filters and add them back, but I did a lot of things in my SelectionChangedHandler, which made this approach very hard to achieve.)
Any help will be appreciated.
From the sencha docs:
As with ListStore, all changes and data are relative to what is currently visible, due to the Store.StoreFilters. As such, if filters are active and structural changes are required, it might be necessary to disable filters to make the change, re-enabling them when finished.
You might have to keep a separate list of all the objects or at least a list of the ones that were filtered out.
Warning: This is my first IPhone Application and I'm new to Objective C, therefore my question might be very basic.
Actually I have a conceptual problem:
I have a one to many relationship between my NSObjects Project and WorkTime (Project<-->>WorkTime). WorkTime has attributes like startDate, endDate, … and a relationship named project to the Project object.
On the UITableViewController subclass that shows my list of WorkTimes, I fetch the CoreData Model with a FetchedResultsController. When I create a new WorkTime, I use a second context and merge it with the "default" once, once the user has clicked on "save" on the drill-down View, like in the CoreDataBooks example from the Apple Documentation. That works well.
The problem starts when I set the relationship. Since the projects are in the “default” context, I can’t assign any project object to the project key in WorkTime, since they are in two different contexts.
So, should I copy all the projects into the “saving” context? Or should I use just one context for everything?
One problem that arises when I use only one context is that the tableview that shows the WorkTimes gets actualized when the user clicks on the addbutton (insertNewObjectForEntityForName). So the list grows right before it presents the new view controller (addWorkTimeDetail) in modalviewcontroller. And if the user clicks cancel in that detail view and decides not to save the WorkTime, I’d have to delete the newly created entity from the context. I don’t think this sounds the way to do it.
Suggestions would be very appreciated!
UPDATE
I'm still having some issues:
When the AddWorkTimeViewController is created from the RootViewController, I create a new NSObject WorkTime. When the user clicks "cancel" I delete the newly created WorkTime and return to the RootViewController. The FetchedResultsController actualizes the tableView and I see a short animation that comes because the object has been deleted. That's doesn't look nice.
I know it would be better to create the object ONLY if the user clicks "save" and by "cancel" do nothing, but I need that object in order to populate the drilldown views with values. The drilldown views work with a NSManagedObject. I see two possible ways to solve this:
1) Have a temporary object TempWorkTime subclassed from NSObject with the same attributes from the WorkTime NSManagedObject. I would create the TempWorkTime in the AddWorkTimeViewController and use it for the drilldown views. I would of course have to subclass them to accept an NSObject instead of a NSManagedObject. I guess type casting wouldn't work. When the user clicks "save", I would create a WorkTime NSManagedObject and pass it the values from the TempWorkTime.
2) Is it possible to trick the FetchedResultsController so that it doesn't update itself while the tableView is not visible? In that case, it would not respond to the changes in the context until it's back in view, and so it would not do the delete animation.
Any suggestions?
SECOND UPDATE - maybe it's useful for people trying to do this same thing
I found this link which proved to be very helpful:
http://www.timisted.net/blog/archive/multiple-managed-object-contexts-with-core-data/
It's very well explained why it's sometimes a good idea to use two contexts. I had some problems with using one context explained in the UPDATE part of my question.
Now I'm using two contexts and it works perfectly, even with relationships. Important is to use the NSManagedObjects of the second context when creating the relationship. That was my mistake when I started to work with this approach.
I don't see why you use two different contexts.
The way to do it is to pass your tableView's context to addWorkTimeDetail, and add any new WorkTimes to that context. If the user cancels, i.e. doesn't create a new object, there will be nothing new in the list when you return. If the user creates the new WorkTime in the context it was passed, it will show up in the list when you return.
In your example, use only one context, and pass it along to your subviews.
I found this link which proved to be very helpful:
http://www.timisted.net/blog/archive/multiple-managed-object-contexts-with-core-data/
It's very well explained why it's sometimes a good idea to use two contexts. I had some problems with using one context explained in the UPDATE part of my question.
Now I'm using two contexts and it works perfectly, even with relationships. Important is to use the NSManagedObjects of the second context when creating the relationship. That was my mistake when I started to work with this approach.
I have a UITableViewController that allows the user to perform editing tasks.
Now, once a user has committed his change, the table view doesn't directly change the model and updates the table, rather "informs" the model what the user wants to do. The model in turn updates accordingly and then posts a notification that it has been changed.
As far as I've seen, I need to begin/end updates on the tableview and in between change the model to its' final form. My changes though, are asynchronous and cannot guarantee to update the model before 'tableview endupdates' is called.
Currently, each time I receive a 'model did change' notificaiton, I reload the entire table.
So, how can I really make cell animations (delete/insert) work?
Should the model fire a notification for each little change instead of the entire table?
You need to store the old array used to display data and compare it with the new array. You can then animate any additions/deletions.
Also, unless you're doing something very fancy, you are not modifying the model but rather a set of data based on the model.