iOS - How to have UITableView with edit mode exactly like Contacts App? - ios

I am building an app that will have it's own list of 'contacts'. It will not be connected to the device's actual contacts app.
However, I want to basically imitate the Contacts app 100%.
That is, have a table view to display user info (done!) and allow a user to edit the user info and have the table view "animate" into a slightly altered table (just like the Contacts App does!).
How does the Contacts app work when it comes to the "transformation" of the table when going into edit mode?

It is all in the UITableView documentation:
When sent a setEditing:animated: message (with a first parameter of
YES), the table view enters into editing mode where it shows the
editing or reordering controls of each visible row, depending on the
editingStyle of each associated UITableViewCell. Clicking on the
insertion or deletion control causes the data source to receive a
tableView:commitEditingStyle:forRowAtIndexPath: message. You commit a
deletion or insertion by calling
deleteRowsAtIndexPaths:withRowAnimation: or
insertRowsAtIndexPaths:withRowAnimation:, as appropriate. Also in
editing mode, if a table-view cell has its showsReorderControl
property set to YES, the data source receives a
tableView:moveRowAtIndexPath:toIndexPath: message. The data source can
selectively remove the reordering control for cells by implementing
tableView:canMoveRowAtIndexPath:
You also use the UITableViewDelegate methods to set up how rows appear in editing mode
– tableView:editingStyleForRowAtIndexPath:
– tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:
– tableView:shouldIndentWhileEditingRowAtIndexPath:
And these methods from the UITableViewDataSource:
Inserting or Deleting Table Rows
– tableView:commitEditingStyle:forRowAtIndexPath:
– tableView:canEditRowAtIndexPath:
If there is something specific you are not sure about please ask something specific.

Related

UITableView data source change does not trigger UI update on iOS 13

This only happens on iOS 13.. iOS 12.x works fine.
I have a table view with a search controller, and two datasources, one for the regular functionality and one for the search functionality. (the search functionality is unrelated to the content displayed on the main table content).
After cancelling a search, the searchBarCancelButtonClicked: method is triggered, I switch from the search data source to the main datasource and reload the table view but even though the table view details show that the correct datasource is set, the UI still shows the search data source.
I tried triggering the layout refresh, but no luck.
Worth mentioning that the UITableViewDataSource methods are called on the correct data source, it's just the UI that's out of sync so to speak.
Any idea what could cause such a thing?
If I manually set the search controller inactive, it works: [self.searchController setActive:NO];

Is it possible to have a UITableView with one row always in edit mode, showing its insertion or deletion control? If so, how?

I have a UITableView with some data, and I'm hoping to put in the top row or section a cell (call it, "Add Record" or something), which is always in edit state, so that it always displays the system insertion control. Is this possible? If so, how?
I've searched all around for this. Apple's documentation lists a setEditing(_:animated:) method on UITableViewCell. I used both that and setting isEditing to true on the cell on load, and it appears to be in isEditing state because the table wouldn't let it be selected until I turned on 'single selection in edit state'. But no insertion or deletion controls show up, and the delegate's tableView(_:editingStyleForRowAt:) is never called.
The cell looks fine if I call setEditing(_:animated:) on the table view itself, but that sets every cel to editing, deletion and all! That's not what I want.
I suppose I can just use a normal cell, and use an image of an insertion control, but I'd rather use Apple's system one if possible (since they might change). Aside: I could always load up an editing table on load and cache a snapshot of an editing control, but that's waaaay more work than its worth!
Is what I'm going for even possible? Do you understand what I'm going for? Any advice you could provide would be very helpful.
You can try the following approach:
Keep using setEditing on the UITableView itself.
To show the editing controls only for a specific cell, implement the
canEditRowAtIndexPath method of the
UITableViewDataSource delegate and return true only for the cell that you wish to allow editing for.
At this point your specific cell will show the editing controls, but the cells are not selectable; you'll need to set allowsSelectionDuringEditing on your table-view
to allow the cells to get selected. Next, you will probably want to
prevent the editing cell from being highlighted by implementing
shouldHighlightRowAtIndexPath delegate method and return true for
all cells except for the cell that you want to keep in editing mode.
Other possible solutions:
Create your own UITableViewCell and implement the editing UI yourself (which will always be visible), then use this cell where you need it.
Use another UITableView with a single cell which will always be in editing mode and place it above your other table so it would appear to be the same table. It's a possible solution but most likely an overkill.

How can I prevent selection of UITableView from changing when details change and the tableview reorders?

In a core data app, I've got a UIViewController that has a "master" tableview on the left, with a set of detail controls (textfields, switches) and another UITableview on the right. (This is the iPad layout.) The tableviews are populated by NSFetchedResultsController instances. When the user selects a row on the leftmost tableview, it populates the details fields accordingly for editing, and the far right table is populated by another NSFetchedResultsController, displaying a set of related objects.
My problem is that for the master tableview, the one on the left, whenever I edit on of the fields related to the sort descriptors of the NSFetchedREsultsController, the table reorders and changes it's selection, which means the user would have to find the desired row and select it again to continue working. Is there a way I can prevent that selection from changing, or at least force it to reselect the proper row after it reorders the data?
It sounds like you are implementing the fetched results controller's delegate in only the most basic way, i.e. calling reloadData from within the controllerDidChangeContent: method. This will clear the table view's selection.
It you implement the fine-grained delegate methods, you should receive multiple changes of type NSFetchedResultsChangeMove during a reordering update, from which you can call moveRowAtIndexPath:toIndexPath:, which should preserve the table view's selection.
Otherwise you can store the model object that is selected in controllerWillChangeContent: and restore the selection from that model object in controllerDidChangeContent:.

numberOfSectionsInTableView is requested in/after viewDidLoad ONLY if tableview is empty

A simple tableviewController, empty. A modal that can be launched from a button. No data in the data source for the tableview, and no rows displayed.
I open the modal, use it to add an item, and return to the tableview controller. The tableview updates itself automatically, and the new row is displayed.
I add a second item. The table view does NOT update automatically.
I can tell by logging inside numberOfSectionsInTableView that even if I go to add the first item and cancel, the tableview refreshes - it asks for the number of sections, rows, and the cell to display (if there is one). But not if there is one pre-existing row in the table.
I've scoured my code but can't find anything that would cause the tableview to know when the first item is added, but none afterwards.
Any ideas?
EDIT - I have further narrowed my issue so will close this shortly and have posted a more specific question at Why does an empty tableView check the number of sections but a non-empty one does not?
from Apple's documentation:
UITableView overrides the layoutSubviews method of UIView so that it
calls reloadData only when you create a new instance of UITableView or
when you assign a new data source.
maybe you are setting data source of table view after showing that modal? So at the second time data source does not changes and tableView does not update.
another key (I'm not sure about that) may be the showing of the modal first time. The method -addSubview for modal is causing -layoutSubviews.

How to refresh a UITableView in iphone?

I have a UI table view loading data from network. If the user move the finger on one cell, one button will be displayed, just like iPhone style delete button. If the user click this button, the value of one label in the cell will be changed accordingly. However, I didn't find any way to make table view to re-draw this cell, except for reload the whole table. I don't want to use reload data method, because I just need change the value in one cell instead of the whole table. Any suggestion on this?
Take a look at the method
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Calling this method will result in your table view's data source asking its delegate for information about that cell.
For future reference, I found this very easily by checking the documentation on UITableView. I suggest you do that in the future before posting here.

Resources