Reload Table View Except for One Cell - ios

I have a table view containing searchable data, and one cell which contains an editable textField (editable with a pickerView). I am using the pickerView to select the section of the tableview to be displayed. However, when a new row is selected in the pickerView, I don't want the pickerView to be dismissed, which is what happens when I use
[self.tableView reloadData];
I've tried the following to solve the problem, attempting to reload the table except for the cell containing the textField:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSIndexSet *toReload = [[NSIndexSet alloc] initWithIndex:1];
if (row == 0)
{
self.selectedDepartmentField.text = #"All";
toReload = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 13)];
}
else
{
self.selectedDepartmentField.text = [self.departments objectAtIndex:(row - 1)];
}
[self.tableView reloadSectionIndexTitles];
[self.tableView beginUpdates];
[self.tableView reloadSections:toReload withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
This crashes with EXC_BAD_ACCESS (code=1,address=0x28)
How should I go about reloading the data in the table to keep the pickerView active?

Following is one possible approach
Get an array of NSIndexPath with
NSArray *visibleIndexPaths = [self.tableView indexPathsForVisibleRows];
Remove the indexpath of the cell with picker from visibleIndexPaths .
Reload the tableview using following method
[self.tableView reloadRowsAtIndexPaths:visibleIndexPaths withRowAnimation:UITableViewRowAnimationNone];
This should reload all visible cells other than one with picker.

Related

Select the row after reloaddata is complete on UITableView

I have a UITableView with custom UITableViewCell and datasource.
My tableviewdelegate class is registered to callback on on an event and once I got the event, I am reloading the data on the tableview.
The call back comes after I edit the tableviewcell data. But once the callback came, when I reloaddata, the tableview is scrolling to the top; and not staying at the current selection.
So I have cached the current selected cell and trying to scrollToRowAtIndexPath.
But I am hitting a crash.
How can I scroll to that row after tabledata is loaded ?
{
[m_tableView reloadData];
if(m_currentEditingCell != nullptr)
{
[m_tableView scrollToRowAtIndexPath:m_currentEditingCell atScrollPosition:UITableViewScrollPositionNone animated:YES];
}
}
You should provide NSIndexPath instead of providing your tableviewcell as argument for the selector scrollToRowAtIndexPath:atScrollPosition: animated:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[yourTableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
The following code is able to select the cell after reload.
{
[m_tableView reloadData]; dispatch_async(dispatch_get_main_queue(), ^{ NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([m_tableView numberOfRowsInSection:([m_tableView numberOfSections]-1)]-1) inSection:([m_tableView numberOfSections]-1)]; if(m_currentCell != nullptr ) [self selectCurrentCell:m_currentCell];
}
}

How to get last cell index path in iOS?

I am building an IOS application where I am using tableView. Now when I reached to last cell I load +10 data from localDB.
After fetching the data I reloaded the tableView that I don't need in place of reload I want to used updated tableView. for that SOF suggested me below code.
[[self tableView] beginUpdates];
[[self tableView] reloadRowsAtIndexPaths:____ withRowAnimation:UITableViewRowAnimationAutomatic];
[[self tableView] endUpdates];
I don't what should be there in reloadRowsAtIndexPaths value. Please can some help me in understanding this above line of code.
You can get the indexPath of the last row in last section like this.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(numberOfRowsInLastSection - 1) inSection:(numberOfSections - 1)];
Here, numberOfSections is the value you return from numberOfSectionsInTableView: method. And, numberOfRowsInLastSection is the value you return from numberOfRowsInSection: method for the last section in the table view.
You don't need to reload cells, because there are no cells after your 10th cell. You want your users to see more cells when they get to the last one as in a news app. The solution is to inset more rows below, here is how:
1- create the rows you want to insert
NSMutableArray *newRows = #[[NSIndexPath indexPathForRow:10 inSection:0]];
3- update your data source array
2- [self.tableView insertRowsAtIndexPaths: newRows, UITableViewRowAnimationAutomatic];

Xcode iOS UITableView Insert New Cell Animation

Thanks in advance. I'm dealing with a single UITableView which is divided into different sections. Users can add or delete cells only from specific sections. The information displayed in the UITableView is stored in an array where each object represents a section:
eg: tableItemsArray = ((arrayForSection1), (arrayForSection2), (arrayForSection3))
I have the animation set up to handle the delete as follows:
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationRight];
I then programmatically remove the item from the array to remove it from the data model. However I am having difficulty in how to insert the cell in an animated form.
Currently I am running the current pseudo-algorithm:
Check item isn't anywhere in the array
Add item to array into a specific section
sort this section of the array alphabetically
reload the data
Update
When a new item is added to the array it is stored in a string to keep record of the new item. Once the array has been resorted I iterate through the array of cells to find its indexPath, then I delete the string (to prevent recursive insertion animations) and perform the animation, however the code doesn't animate its insertion into the table. I wondered whether that maybe the animation code (as below) wasn't working as I was using [tableView reloadData]?
// For Each Section in the table:
for (NSMutableArray *object in sectionsInTable) {
// For Each Cell in a section (Cells are stored in an array in index 1)
for (NSString *label in [object objectAtIndex:1]) {
if ([label isEqualToString:_insertedObject]) {
// New item
_insertedObject = Nil;
// animate addition
[self.labelListTableView beginUpdates];
[self.labelListTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:[[object objectAtIndex:1] indexOfObject:label] inSection:[sectionsInTable indexOfObject:object]]] withRowAnimation:UITableViewRowAnimationBottom];
[self.labelListTableView endUpdates];
}
}
}
Any ideas why the animation isn't working?
Thanks
D
Seems that the [tableView reloadData] was preventing the animation.
// Annimate the new Item
// For Each Section in the table:
for (NSMutableArray *object in sectionsInTable) {
// For Each Cell in a section:
for (NSString *cell in [object objectAtIndex:1]) {
if ([cell isEqualToString:_insertedObject]) {
// New item
_insertedObject = Nil;
// animate addition
[tableView beginUpdates];
NSInteger section = [sectionsInTable indexOfObjectIdenticalTo:object];
NSInteger row = [[object objectAtIndex:1] indexOfObjectIdenticalTo:cell];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
[tableView insertRowsAtIndexPaths: [NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationBottom ];
[tableView endUpdates];
}
}
}

Update Specific cells in a tableView without calling reloadData

I have an app in which I have a UITableview with custom cells and headers. The cells have an inputView so when selected they become first responder and allow the user to input data.
I want to be able to update the visible TableViewCell and header information on the fly while the user is changing it.. easy, just call [tableview reloadData]; ..
Unfortunately this causes the inputview to resign first responder and hide itself.
Is there any way that I can get a reference to the cell itself inside the UITableview so that I can just change the text property? (cellForRow:atIndexPath: returns a new object with the same properties so doesn't work) It seems like the only easy solution may be to store a reference the cells in a dictionary each time a cell is populated, not really the ideal solution.
cellForRowAtIndexPath is literally just
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *orderCell;
static NSString *productCellIdentifier = #"ImageDetailCellIdentifier";
orderCell = [self.tableView dequeueReusableCellWithIdentifier:productCellIdentifier forIndexPath:indexPath];
//set a bunch of properties orderCell.blah
return orderCell;
}
According to UITableView documentation, -cellForRowAtIndexPath: returns an object representing a cell of the table or nil if the cell is not visible or indexPath is out of range.
That is also how I remember it. I don't think your observation is correct that it returns a new object. If the cell is visible you will get hold of it.
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade]; ///as your choice in animation
[tableView endUpdates];
or else
[tableView beginUpdates];
// do some work what ever u need
[tableView endUpdates];
For reloading specific rows, you can use
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
For example,
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:2 inSection:1];
NSArray* indexArray = [NSArray arrayWithObject:indexPath];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

UITableViewCell loses highlighted selection

I am using [tableview reloadData]; to reload the data in my UItableView, however when I use this I loose my highlight on my UItableVewCell.
I would like to know the best way to reinstate this highlight.
I set a tempIndexPath when the user selects the cell they edit the information then I call reloadData, then inside cellForRowAtIndexPath I use this code to re-highlight the cell however its not working.
if ([tempIndexPath isEqual:indexPath]) {
cell.selected = YES;
}
This code keeps the highlighted selection, and is safe with resorting/inserts/repositioning since it keeps a reference to the underlying object from the model, instead of the index path. It also scrolls to the selection, which is helpful when the updated model causes the selection to be moved out of the current scroll position's frame.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Save the selected object at this row for maintaining the highlight later in reloadData
_selectedItem = [_items objectAtIndex:indexPath.row];
}
- (void) reloadData
{
[_itemsTable reloadData];
//Reselect and scroll to selection
int numItems = _items.count;
for (int i = 0; i < numItems; i++) {
NSDictionary *dict = [_numItems objectAtIndex:i];
if (dict == _selectedItem) {
//This is more reliable than calling the indexPathForSelectedRow on the UITableView,
// since the selection is cleared after calling reloadData
NSIndexPath *selectedIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[_itemsTable scrollToRowAtIndexPath:selectedIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
[_itemsTable selectRowAtIndexPath:selectedIndexPath animated:FALSE scrollPosition:UITableViewScrollPositionNone];
break;
}
}
}
Save the selected row, reload your table view's data and select the row again.
NSIndexPath* selectedIndexPath = [tableView indexPathForSelectedRow];
[tableView reloadData];
[tableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
You should know that this is dangerous, because if new items were added to the table view before the selected row, the selection will not be the correct cell. You should calculate how many rows were inserted before the row and adjust the selectedIndexPath accordingly.

Resources