Here is a short summary of the situation:
I have a TableViewController with a number of cells.
In one of the cells I have a UITextField. This cell is of a custom UITableViewCell class. This class implements the UITextFieldDelegate protocol and the method textFieldDidEndEditing:
Within the method textFieldDidEndEditing: I store the value of the TextField into CoreData.
This all works great.
My question relates to reloading the TableView:
After certain actions of the user I reload the data of the UITableView by calling [self.tableView reloadData]
If, when I call this method, the above mentioned TextField is first responder, the textFieldDidEndEditing: method will be called, causing my CoreData related code to execute.
When the TableView is being reloaded I do not want the custom TabelViewCell to do anything at all.
Is there a way, the TableViewCell can be aware of the TableView being reloaded? So I can check for this within the textFieldDidEndEditing: method?
In the meantime I have solved it in the following way:
When this TableViewCell is being created I let the ViewController store a reference to it.
Before calling [self.tableView reloadData] I first inform the Cell by setting a custom property _cell.tableWillReload = YES
I will check for this property within the textFieldDidEndEditing: method.
I was thinking maybe there is a different, more default way, for TableViewCells to know they surroundingTableView is reloading?
Try This :-
[yourTextFieldOfCell resignFirstResponder];
before calling [self.tableView reloadData];
Related
How to add UIPickerView in UITableView in didSelectRow method ,
Based on picker selection user select different options in each cell
First, when you want to ask a question, you should add some code pieces that you tried. In this way, people can help you using your work.
ANYWAY, I suggest you two ways:
Create a custom UITableViewCell class and in setSelected: method create a UIPickerView and add it to window. Set its delegate and dataSource. Use delegate methods to get data and use dataSource methods to set data to UIPickerView.
In UITableView's tableView:didSelectRowAtIndexPath: method and implement UIPickerView delegate and dataSource methods same as in first option. Update cells' data using these methods.
I have some rows of my UITableView that get updated and then trigger the method controller:didChangeObject:atIndexPath:forChangeType:newIndexPath of the NSFetchedResultsControllerDelegate delegate.
I usually update the rows in the tableView using reloadRowsAtIndexPaths with an animation, but it happens that sometimes the method is triggered because of a change that is not visible and is that case, I don't want to reload the row with an animation.
The method doesn't give the previous state of the object. Is there a way to do it (I didn't find any method of the delegate that might do)?
If your delegate is also your TableViewController, you could just check your UITableView's data source at the IndexPath. The reloadRowsAtIndexPaths method knows the index.
I have a custom UITableViewCell that dequeueReusableCells. I have an int called selectedRow which gets the selected rows number in the method of didSelectRowAtIndexPath. I then pass selectedRow to an int called rowNumber which is in the class of my customCell.
In customCell.m, I have the method prepareForReuse. In that I made an NSLog of rowNumber.
What I want to do is: if a row is selected and that row went off screen, then perform some code. I would probably have to use prepareForReuse, but I don't know what to do in it.
I know it's a bit complicated, but if you have any questions, then I'd be happy to answer
Actually, you don't need to call prepareForReuse directly as it would be called automatically:
this method is invoked just before the object is returned from the
UITableView method dequeueReusableCellWithIdentifier:.
and as you don't know what to do in it, note:
For performance reasons, you should only reset attributes of the cell
that are not related to content, for example, alpha, editing, and
selection state
UITableViewCell Class Reference
You can use - (void)tableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath; in UITableViewDelegate to know which cell is scrolled off screen.
However, this method is iOS6+ only.
You're over complicating things. You don't have to do prepareForReuse the in the custom cell.
Take a look at this.
http://www.icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/
Its pretty similar for storyboards.
I have a UITableView with four cells, in single selection mode. When the view is first loaded, I programmatically select one of the cells using -selectRowAtIndexPath:animated:scrollPosition: based on a stored preference. After this, the user can interact with the table.
The methods -tableView:willSelectRowAtIndexPath: and -tableView:didSelectRowAtIndexPath: are called on my table view delegate every time the user taps any cell. However, -tableView:willDeselectRowAtIndexPath: and -tableView:didDeselectRowAtIndexPath: (that's DEselect) don't start being called until the user manually taps that first programmatically selected cell.
Any idea why this might be happening? Are there any workarounds besides manually calling -[UITableView selectRowAtIndexPath:animated:] for every cell except the one that the user tapped?
If you do invoke [UITableView selectRowAtIndexPath:animated:] too soon and you are using a UITableViewController, you probably have conflict with the UIViewController clearsSelectionOnViewWillAppear (defaults to YES). Try setting self.clearsSelectionOnViewWillAppear = NO; in your viewDidLoad
This is too long for comment so I'm posting this as an answer.
Just created test project with tableView. I call [UITableView selectRowAtIndexPath:animated:] on viewDidLoad and I have one cell selected. Then I'm selecting another cell (without deselecting first one).
I have this output:
[SDTVTViewController tableView:willSelectRowAtIndexPath:]
[SDTVTViewController tableView:willDeselectRowAtIndexPath:]
[SDTVTViewController tableView:didDeselectRowAtIndexPath:]
[SDTVTViewController tableView:didSelectRowAtIndexPath:]
And I have first cell deselected and second one selected.
I have no idea, why it's not working in your code. When you're calling [UITableView selectRowAtIndexPath:animated:] and can you post code of UITableViewDelegate methods that you've implemented?
I was wrapping my initial data source updates and -selectRowAtIndexPath:... calls in
[_tableView beginUpdates];
// ...
[_tableView endUpdates];
Apparently, like -reloadData, this clears the current selection (not sure if that's by design). I moved the call to -selectRowAtIndexPath:... to after -endUpdates and now everything works as intended.
As a user scrolls up and down in an uitableview cells get destroyed and created.
Is there a way to detect when a cell is going to be or has been destroyed?
Assuming that by "getting destroyed" you actually are referring to a cell getting reused, simply implement prepareForReuse within your UITableViewCell derived class.
prepareForReuse
Prepares a reusable cell for reuse by the table view's delegate.
- (void)prepareForReuse
Discussion
If a UITableViewCell object is reusable—that is, it has a reuse
identifier—this method is invoked just before the object is returned
from the UITableView method dequeueReusableCellWithIdentifier:. For
performance reasons, you should only reset attributes of the cell that
are not related to content, for example, alpha, editing, and selection
state. The table view's delegate in tableView:cellForRowAtIndexPath:
should always reset all content when reusing a cell. If the cell
object does not have an associated reuse identifier, this method is
not called. If you override this method, you must be sure to invoke
the superclass implementation.
Availability
Available in iOS 2.0 and later.
See Also
– initWithFrame:reuseIdentifier:
#property reuseIdentifier
Declared In
UITableViewCell.h
Without going into the implications of suitability or performance, another option might be to periodically check what cells remain visible, using the visibleCells method of the UITableView class:
- (NSArray *)visibleCells
As per the documentation:
Returns an array containing UITableViewCell objects, each representing a visible cell in the receiving table view.
You can subclass UITableViewCell and override it's dealloc method.
Any good reason to do it assuming you are reusing the cells to save the resources ?
What you're attempting to intercept is part of the internal implementation of UITableView and how it manages its cells. While there are ways in which you can attempt to intercept such behavior, I would suggest that you avoid using them, as there is no guarantee that future implementations of UITableView will maintain this behavior.
It would be better in cases such as this to consider a different approach: be it design and implement your own table class, or change your code logic.
As stated above, cells aren't destroyed when the leave the screen. However there are some things you can do, to track related actions, depending on what you are trying to do.
First there is a delegate message:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
This is called before a cell enters the screen. Another possibility is the already stated prepareForReuse method of a cell.
Another approach would be: Try and override willMoveToSuperview: or any other of the related methods. I am not sure if this is fired after the cell becomes invisible, but it might work.
Best regards,
Michael