Set editing style on a UITableViewCell without reloading the cell - ios

I'm building a view controller that is very similar to the Contacts app ABPersonViewController in editing mode.
I have a UITableView filled with Custom UITableViewCells which contain a UITextField where the user can enter a phone number
I have a situation where if someone starts entering in a new phone number (in the last cell of the section), a new empty table view cell is added to the bottom of the table, and the editing style of the current table view cell is set to UITableViewCellEditingStyleDelete, like in the Contacts app in the same situation.
My problem is that I don't know how to change the editing style of the UITableViewCell without reloading it. The problem with reloading it is that its UITextField that is currently being edited will be released, dismissing the keyboard.
Is there a way to change the editing style of the UITableViewCell without reloading it? Or another way of accomplishing what I want?

Yes, just use the UITableViewCell method setEditing:animated:.

I was able to accomplish what I wanted by following the answer here:
https://stackoverflow.com/a/5664207/472344

I have successfully set editing cell with multiple selection applying below code:
[self.tableView setEditing:YES animated:YES];
self.tableView.allowsMultipleSelectionDuringEditing = YES;
// Add these two lines can fix icon issue.(First time enter edit mode still show delete icon.)
[self.tableView beginUpdates];
[self.tableView endUpdates];

Related

INSERT a new UITableView row with Editable UITextfields

I've been working on this for many days now and cannot seem to make it work. It may not even be possible but there's gotta be a way!
I want to insert a new uitableview row that contains two uitextfields that are editable after insertion. Everything I've read says you should update your data model array before the cell is added, meaning that the texfields need text in them and then added to the array BEFORE inserting the row. I tried to add a prompting text but once the cell is added, I can tap into the textfields, but I can't change what's already there (my prompting text). The textviews are unreponsive other than being able to tap into them. How to do this?
I am presenting a UIDatePicker to fill in the textfields for a single row that is created when the app first boots up. I want users to be able to add another row for when they read a book a second time (or more!). The textfields no longer update with the datePicker's values once the next row is added.
I've tried to use an alertview with textfields in it (I'm using URBAlertView) so users can add their dates before adding the new row, but I haven't been able to get it to go.
Please let me know if you need more code or if this is even possible. Thanks in advance for your help!
- (IBAction)addNewRowButtonTapped:(id)sender {
[self showDatePicker];
[self.tableView beginUpdates];
_cell.startDateTextfield.text = #"add start date";
_cell.finishDateTextfield.text = #"add finish date";
//these two lines give me errors and causes a crash
//[_book.startReadArray addObject:_cell.startDateTextfield.text];
//[_book.finishReadArray addObject:_cell.finishDateTextfield.text];
NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:[_book.startReadArray count]-1 inSection:1]];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop];
_numberOfRows ++;
[self.tableView endUpdates];
}
This should be relatively simple, create a custom view with a UITextField, make sure it is properly registered with the tableView so you can dequeue it, and your UITextField should be useable.
I've setup a demo project for you that demonstrates this: https://github.com/ekscrypto/Swift-Tutorial-InsertTextfield

UITableView within UITableViewCell does not get updated

I have tried to create a custom cell that would display a list of items. To achieve this I tried to create a custom cell with UITableView inside it with scroll disabled.
The problem I have with this is when i try to apply changes to the cells in the inner UITableView data just does not get updated and the cell stays as it was. I have tried calling [tableView reloadData], [cell setNeedsDispaly], [cell setNeedsLayout] to no avail.
It seems like the data that has been applied when the cell was initialised persists through any attempts to change it. Though, when I create a breakpoint in cellForRowAtIndexPath: the data does get updated but is not rendered.(e.g. text property of UILabel has new value, but text is old on the screen.)
You need to nil the cell and then reload the table view. For some reason iOS caches table view data and stuff doesn't get updated correctly.
You could try overriding UITableViewCell's prepareForReuse(): in that method you can set all the cell's outlets/properties to nil. You would do this for the cells in the main cell's table view. I am assuming those are custom cells as well and that you have a custom UITableViewCell subclass for them.
Refer [I have two views on one cell, when I click on a cell it will be hidden and one edit form will be expanded on that. How to resolve that? ..check in accepted answer methods ...
[tableView reloadRowsAtIndexPaths:ll withRowAnimation:UITableViewRowAnimationAutomatic] in didSelectRowAtIndexPath

Updating UITableView cells according to the text entered in a text filed that is in the same main view

Is it possible to update the cells of a table according to the value entered in the text field which is in the same view or when clicking on a button which is in the same view. can this be done when all the components are in the same view? of course i know that i will have to use a cell and a table view an all in that view.
If it's possible please hint me to what method in the TableView Delegate I should work with to make this happen or if I have to write a custom method.
Thanks in advance.
You should look into UISearchController
Links to explore:
http://www.raywenderlich.com/16873/how-to-add-search-into-a-table-view
http://jduff.github.io/2010/03/01/building-a-searchview-with-uisearchbar-and-uitableview/
http://www.iphonedeveloperdiary.com/2010/07/adding-a-uisearchbar-to-top-part-tableview/
http://www.iphonedevsdk.com/forum/iphone-sdk-tutorials/38913-slicks-uitableview-series.html
https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UISearchDisplayController_Class/Reference/Reference.html
OR...
If you want to do it using something like a simple UITextField, then in the -textFieldShouldReturn, you can use NSPredicate to create an array of searched objects and then simply can do a [self.tableView reloadData].
(just ensure that the datasource of your tableView is using this array)
You can do it just by using
[tableView reloadData];
On Clicking if button please ensure to update UITableView Datasource Array to update.

Hide Delete button from UITableViewCell

When my table view is in edit mode, the red (-) buttons appear.
When the user taps one of them the [Delete] button appears.
When the user taps on [Delete] I first check a few things (partly online). This delete may not be allowed.
When deleting that cell is not allowed, how do I hide the [Delete] button and let the red (|) button become a (-) again in an animated way? So, I don't want my whole table to leave editing state.
To get the actual animation (Instead of the UITableViewRowAnimationRight/UITableViewRowAnimationAutomatic) animations, just do
[self.tableView beginUpdates];
[self.tableView setEditing:NO animated:NO];
[self.tableView setEditing:YES animated:NO];
[self.tableView endUpdates];
beginUpdates and endUpdates provide the animation, and the tableView is just switched from not editing to editing instantly, which closes the delete button.
Hope this helps!
I've run into this issue myself where I may bring up an alert view to prompt the user further and wish to reset the delete button if they choose not to proceed. This seems like the easiest approach, assuming deleteIndexPath is the index path of the row selected for deletion:
[self.tableView reloadRowsAtIndexPaths:#[deleteIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
I now see that you want to disable delete for only certain cells. You can do this in a couple of ways:
tableView:canEditRowAtIndexPath method: Return NO where you want DELETES to be DISABLED.
tableView:canMoveRowAtIndexPath: Return YES where you want to allow reordering.
You may want to think about sub-classing UITableViewCell to give it some ability to maintain its own state (so the cell knows if delete is allowed or not. Then you can interrogate the actual cell instance and determine if you should enable delete even after the list may be re-ordered.
To hide any icon in whole table view, then in your controller just ,
override EditingStyleForRow and return UITableViewCellEditingStyle.None
None: will hide any icon of left of items of table view,
delete: will show remove icon
Insert: will show add icon

UITableView stop updating UI without crashing after adding data

I have a problem that is driving me crazy.
I have an UITableView that is always in editing mode (it has to be).
The user can add new rows to it.
The navigationItem.leftbarButton of the tableViewController pushes a new controller just to do it, let's call it "newRowsVC".
Before the push the tableViewController set itself as the delegate of the newRowsVC, the protocol has only a method:
-(void) aNewRowHasBeenCreated
{
[self.tableView reloadData];
}
I start adding rows and everything works fine, each now row is immediately displayed in the tableViewController until the last new row will force the tableView to scroll because there won't be anymore screen real estate for it. Here, I have no idea why, the tableView, only it, is as frozen, with no scrollbar and doesn't respond to input. The app continues to run without a crash and I can even dismiss the tableViewController by tapping the navigationItem.rightbarButtonItem.
I can keep creating new rows, they are added to the array, the number of row in the tableView data source is computed correctly. But the table is like dead.
If I dismiss the tableViewController and then I come back to it, I see that all the rows previously created, also the ones not shown as soon as they were created are there!
I really do not have idea of how I can fix this.
The first thing I tried was to force the scroll after the reload of the table but it didn't fix it.
-(void) aNewRowHasBeenCreated
{
[self.tableView reloadData];
[self.tableView setScrollEnabled:YES];
}
I also tried forcing the tableView to scroll to the last row but it didn't fix it.
-(void) aNewRowHasBeenCreated
{
[self.tableView reloadData];
[self.tableView setScrollEnabled: YES];
[self.tableView scrollToRowAtIndexPosition: [self.tableView indexPathsForVisibleRows]last object] atScrollPosition: UITableViewScrollPositionBottom animated:YES];
}
I check the number of rows each time the table is reloaded. No error, the number is perfect and the new rows data are correctly in the array, also the data for the cells not shown.
I thought it could be because the tableView is always in editing mode so I tried setting it to NO but nothing changes, id din't fix the problem.
Two notes:
1)the tableView has to be the delegate of each one of it's custom cells. They have an UITextField and an UIStepper, handled by the tableViewController. I already tried to not set the tableViewController as the delegate of its custom cells but nothing changes so the problem is not this.
2) self.tableView.bounces = NO but this has nothing to do with the scrolling issue, the scroll is enabled.
Update: After more tests I found that if I remove the dequeue of the reusable custom cell everything works fine, so the problem should be about the reuse.
static NSString *CellIdentifier=#"MyCell"
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
Nicola
After hours I got it. As pointed out by Amit the problem was hidden in cellForRowAtIndexPath... It was hard to catch because it didn't happened all the times and the first times I enabled/disabled the cell reusing everything seemed the same so I did not link the problem to it. I got back on it after I tried about all the other options I had been able to think about.
The problem was in the reuse of the cells and the fact that the custom cell has the tableView as its delegate to handle its textView and the stepper without exposing them.
I got rid of all the delagion stuff and exposed the textView and the stepper as public properties of the view. By doing this I was able to set the tableViewController directly to be the delegate of the cell.textView and to add directly a target/action for the stepper.
Everything works flawslessly now.
Thanks to everyone who tried to help me!
Nicola

Resources