iPhone tableview does not create cell for added row - iphone

I have a SQLite DB containing tasks. Each task has a date, and there can be multiple tasks per date.
My app loads the data for one month only into a mutable dictionary. The key of each dictionary item is a string of the day of the month (1, 2, 3 ... 31). The corresponding value is an array of tasks for that date. Thus, for each day of the month, there is an array of 0 or more tasks.
The mutable dictionary is declared in the root viewcontroller. The root viewcontroller in Interface Builder is the dataSource and delegate of the table view. Somehow the app knows that the root viewcontroller gets its data from the mutable dictionary. I don't specify this, so I wonder what would happen if there were more than one dictionary, or maybe a dictionary and a mutable array? Nonetheless, this works without additional wiring. When the root viewcontroller loads the data into the table, each section header holds the date as its text, and lists all the tasks in individual cells underneath. Some headers have no cells.
Now, to modify a task, I have an "entry" viewcontroller. Selecting a task in the table causes the entry viewcontroller to load that task info into text fields, where I may change the title, date, details, or mark it as done. After editing, the entry viewcontroller unloads, the root (table) viewcontroller reloads, the view's tableView calls reloadData and the changes are apparent.
HERE'S THE PROBLEM: if I ADD a new task by clicking the + button on the nav controller, it takes me to the same entry viewcontroller, where I set the data. I return to the root viewcontroller via the same methods as when editing existing data. Yet no new cell has been created for the new data! If I close and reopen the app, the new data displays correctly.
Since data updates and inserts are written to the DB from the dictionary's arrays when the app closes, this means that the new item really was added to one of the arrays.
Summary: edit existing array item, and the new data is displayed when the table reloads its data. Add an array item, and it is ignored when the table reloads.
What's wrong?

You might add a line like this in your UITableViewController:
[self.tableView reloadData];
This will cause the entire UITableView to be reloaded. However, I believe the preferred method is:
[self.tableView insertRowsAtIndexPaths: indexPaths withRowAnimation: YES];
For this to work, you need to know where the row(s) will appear (the array of NSIndexPaths).
It may be easier to update the UITableViewController from within the "entry" ViewController.

Related

NSTableVIew bound to NSArrayController doesn't save changes

I have a very simple project containing an NSTableView with 3 columns and buttons for adding new row, removing row and saving the data.
For the purposes of this project I want to save the values into the NSUserDefaults db AND to do all this with no coding, so the IB connections and properties are as follows:
Added Array Controller object via IB. Its Controller content is bound to Shared Users Defaults Controller (Controller Key:values, Model Key Path: myvalues), Handles Content as Compound Value checked.
Added the table view set to have 3 columns and set as view-based.
For the table view itself, its Content is bound to Array Controller (Controller Key arrangedObjects) and its Selection Indexes are bound to Array Controller (Controller Key selectionIndexes)
For each column of the table, the Table View Cell item (third in chain) Value is bound to Table Cell View (Controller Key empty, Model Key Path set to objectValue.xxxx where xxxx is an arbitrary name string for the column); also the Behavior attribute is set to "editable".
The add row and remove row buttons sent actions are connected to the Array Controller add and remove methods and the Save button sent action is linked to the Shared User Defaults save method.
When I run the project I can initially do "add", enter the values for the columns, click on Save, end execution and when I re-run it the data is shown. However, if I then try to change any of that data, the changes won’t be kept. If I add additional rows, and enter data that data is not kept (the rows will be there, just empty). Removing rows works as expected. (NOTE: also if I added several rows on the initial execution, only the first would have data on subsequent executions)
My question is: Why won’t data changes (after the first) work? It seems like there’s a missing layer somewhere.
I created a second project, very similar to first, but specified cell-based table rather than view-based; also the bindings are simpler with NO bindings for table-view but just directly bind table cells Value to Array Controller. This project works perfectly. Cell data can be edited, new row data entered, etc.
Any help would be appreciated
Since the cell-based table works as expected, with no coding, I'm going to use that for now. As for getting the view-based table to work properly, it appears (from Ken's notes and other SO threads) that the managed content is probably being updated properly but the user default controller is not being made aware of these changes. So a simple workaround would be to add a couple of lines of code, for example in AppDelegate applicationWillTerminate method:
let ac : NSArray = arrayController!.arrangedObjects as NSArray
NSUserDefaults.standardUserDefaults().setObject(ac, forKey: "myvalues")
where arrayController is an outlet for IB Array Controller.
(This is a bit of overkill as it would set the object every time the app runs, but you could also connect the SAVE button to a method that would set a Bool and then issue the setObject conditionally on SAVE being requested.)

UITableViewCell is frozen (not rerendering with new data). How to fix?

Having some issues with a tableViewCell freezing. I have a table view cell with a list of exercises. When I add a new exercise on another viewController, then pop back to this tableViewController that lists all the exercises, the respective cell gets frozen (see screenshot). Then, if I call [self.tableCell reloadData], that cell never refreshes.
it's weird because if the offending cell is, say, index #4, and I change the data source to only have 2 items, the 4th cell is still frozen. (the first 2 render correctly, the 3rd is blank, 4th is offending cell)
List of all exercises:
When I change the data in the tableView data source, that cell is still frozen:
If I put a breakpoint and inspect the tableView, it doesn't say anything about that frozen cell:
Not sure where to go from here :( It seems to only happen when I insert a row from a different viewController then pop back to this one.
Any thoughts? Thanks so much for any help!
You are keeping a reference to a cell. That is a bad idea. It contradicts the whole pattern of datasource and recycling of table cells. All kinds of wacky bugs will be the inevitable result.
Instead, you should make sure your datasource methods return the correct number of sections and rows, and the appropriate cells and then reload your table not a cell.
[self.tableView reloadData];
So, for example, when the view is returning from adding a new item, make sure the data array you are using is updated and reload.
I exactly don't understand your way of managing tableview along with data source. If you make any change in data source, same changes should be reflected in tableview as well. (Both should be synchronized). You can use:
Table reloadRowsAtIndexPaths:
Table deleteRowsAtIndexPaths:
Table insertRowsAtIndexPaths:
to make changes to your tableview and its cells. Or you can just call [Table reloadData]
Remember: never try to store references of UITableViewCells as they are dequeued again on screen - your reference will be just a trash. Just alter your cells using above 3 methods and you are good to go. If you want to clear something, just ask for it.

Update table cell on notification

How can I update a tabelview cell when a particular notification received, without reloading table data. notification tells the id of the cell that I need to update. So I want to iterate all table cells and update only the relevant table cell without reloading it. how can i do this
Use [tableView visibleCells] to get a list of all cells that are displayed. Iterate through this array to see if the cell you need to update is displayed, then do whatever you need to. (this method is if you're reusing cells).
You can just use the built in reloadRowsAtIndexPaths:withRowAnimation: instead of trying to usurp the framework's functions. This will efficiently only reload the cell you ask it two not the entire table or even an entire section.
Reloads the specified rows using a certain animation effect.
Reloading a row causes the table view to ask its data source for a new cell for that row. The table animates that new cell in as it
animates the old row out. Call this method if you want to alert the
user that the value of a cell is changing. If, however, notifying the
user is not important—that is, you just want to change the value that
a cell is displaying—you can get the cell for a particular row and set
its new value.
When this method is called in an animation block defined by the beginUpdates and endUpdates methods, it behaves similarly to
deleteRowsAtIndexPaths:withRowAnimation:. The indexes that UITableView
passes to the method are specified in the state of the table view
prior to any updates. This happens regardless of ordering of the
insertion, deletion, and reloading method calls within the animation
block.
Available in iOS 3.0 and later.

Refreshing/releasing 2nd tableview from previous query in drill down tableview

I have a drill down tableview that is using sqlite.
The first one is a tableview where i load some categories using a SQL query.
When i click a row it's using the following query to show the appropriate records for the category:
#"SELECT * FROM table WHERE category IS ('%#')", sharedSingleton.category];
This works.
When i click the back button on tableview 2 and return to the category tableview and then touch another category tableview2 still shows the rows for the category i selected the first time.
I'm new to this stuff but i searched a long time and tried releasing objects or set value's to nil but is doesn't seem to help.
Am i in the right direction, how can i refresh or release tableview2?
Thanks in advance.
Yes you are in the right direction.
When selecting a row table 1 you might be calling a method which loads the second table view and assigning the data to be loaded to the corresponding table view,Which is fetched and filled when delegate/ data source methods of table view is called.
You might have created tableview as a different view controller class, which is initialized and data is reloaded for the first time. But even though you are fetching the second set of data its not getting reloaded automatically even after you are assigning it.
After assigning the data you have fetched into the obect which distributes it to tableview Reload the table data once you assign it to. you could call the one line of code to do this
[tableview reloadData];
Regards,
Jackson Sunny Rodrigues

UITableView's reloadData isn't resorting the cells

I have a UITableView that implements NSFetchedResultsControllerDelegate. When I tap a cell, I load another viewcontroller which allows me to edit an entity represented by the tablecells. When I'm done editing, it sends a message to the UITableViewController which does a [self.tableview reloadData];
My problem is that reloadData doesn't seem to resort the data after I've modified it. How do I do this. How do I get it to do so?
Not clear what is that you are trying to do. However if you want cells to be in a different order for a table view you must sort its data source, so if first you want it in order 1 2 3, then in your data source they will be in that order, but next if you want them 2 1 3 then you must resort your data source to contain 2 1 3 in that order, it all depends on what you are returning in cellForRowAtIndexPath for each index path, the sample i gave is assuming y ou are using the row indexpath to index into an array that i s your data source..hope this helps
You can pass the NSSortDescriptor to the NSFetchedResultsController, but have you actually executed a fetch?
You need to save the changes using [NSManagedObjectContext -save:] and then your NSFetchedResultsController will pick up the change and notify the table view to update. You do not need to call -reloadData because it will be handled for you.
Make sure that your UITableViewController is the delegate for the NSFetchedResultsController so that it can handle the update.