Getting UITableViewCell from its superview iOS 7 issue - ios

I have few UI objects in the cell that have got gesture recognizer instance. I need to get cell where pressing object is located. I have the method below for getting it, but it just work before iOS 7:
UITableViewCell *cell = (UITableViewCell *)[[[sender view] superview]superview];
for iOS 6 it return UITableViewCell
for iOS 7 it return UITableViewCellScrollView
I think the new cell has some additional views in iOS 7, that's why I grab UITableViewCellScrollView instead of UITableViewCell as before.

The best way to get a table view cell from it's subview is to convert the subview's location to a location in the table view, then ask the table view for the index path of the cell at that point:
CGPoint subviewPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:subviewPosition];
Then, you can get the cell for that index path:
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];

As you can see, relying on the view hierarchy is not a good approach - Apple can break it at any time.
You should use a delegate protocol to connect your cell to the controller.

CGPoint subviewPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:subviewPosition];
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSIndexPath *path=[self.tableView indexPathForCell:cell];

Related

I need to access the title of a selected row of a Table View outside the TableViewDelegate

I need to access the title of a selected row of a Table View.
But the issue arises when i need to access it outside the TableViewDelegate, i.e. : cellForRowAtIndexPath, didSelectRowAtIndexPath, etc.
Is there anyone who could help me.
Thanks in advance.
How about this ?
- (IBAction)ButtonAction:(id)sender {
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:tableView];
NSIndexPath *selectedindex = [tableView indexPathForRowAtPoint:buttonPosition];
UITableViewCell *Cell = [tableView cellForRowAtIndexPath:selectedIndexPath];
}

Custom delete button for UITableViewCell without editing mode?

I made a UITableViewCell nib with a button on it. When the button is pressed, I want to delete the cell. The table view isn't in editing mode and I'm not using a standard UITableViewCell delete button.
I could store the row number in the button tag from cellForRowAtIndexPath, and use that to determine the row to delete, but when a cell is deleted, the button tags will be incorrect.
Any ideas how I can identify what button press relates to what row?
Like in this answer:
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
If your button is a subview of cell's content view (as it should be). You can get the index path for the cell with button like this:
UIView *cellContentView = yourButton.superview;
UITableViewCell *cell = cellContentView.superview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
Then, just delete the cell:
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
if the method the button calls has a signature like:
-(void)action:(id)sender;
sender will be the UIButton that called the action so:
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = [[button superview] superview];
should get you what you want.

Callback for cellForRowAtIndexPath?

My Project:
I have an UITableView in My project. Each and every UITableViewCell have one UITextView as a subview. When user tap on 'Add' button, I need to add one more UITableViewCell with UITextView to UITableView and I have to set focus into the added UITextView.
What I've Tried:
Once user tap on add button, I will update the numberOfRowsInSection of UITableView and subsequently I'll call [UITableView reloadData] to invoke [UITableView cellForRowAtIndexPath]. Here, I'll append the UITextView as subview of UITableViewCell.It Works fine until this point.
My problem:
I need to set focus into the UITextView Once after the [UITableView cellForRowAtIndexPath] get called. When I called the set focus method for UITextView after [UITableView reloadData], It is not working. I want to know, Is there any callback method for [UITableView cellForRowAtIndexPath]?
Thanks for your answers.
Try this,
In Add button action
//Assuming only 1 section, if you have more section find sections by `numberOfSections` method
NSInteger totalRows = [self.tableView numberOfRowsInSection:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:totalRows inSection:0];
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
//If you have custom cell
CustomCell *cell = (CustomCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell.textView becomeFirstResponder];
//If you are not using custom cell, then set tag to textView and
//UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//UITextView *textView = (UITextView *)[cell viewWithTag:kTextViewTag];
//[textView becomeFirstResponder];
after you have called your reloadData method you can do something like this:
To get a reference to the last row in the last section…
// First figure out how many sections there are
NSInteger lastSectionIndex = [self.myTableView numberOfSections] - 1;
// Then grab the number of rows in the last section
NSInteger lastRowIndex = [self.myTableView numberOfRowsInSection:lastSectionIndex] - 1;
// Now just construct the index path
NSIndexPath *pathToLastRow = [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex];
//Grab a reference of your cell from the last row
MyCustomCell *myCC = [self.myTableView cellForRowAtIndexPath:pathToLastRow];
//Use this cell reference to set focus to your UITextView
[myCC.myTextView setFirstResponder:YES];

indexPathForCell returns nil since ios7

my app was running fine under ios6.1. tried the ios7 simulator and the following part does not work:
EditingCell *cell = (EditingCell*) [[textField superview] superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSLog(#"the section is %d and row is %d", indexPath.section, indexPath.row);
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *rowKey = [[keysForRows objectAtIndex: section] objectAtIndex: row];
It always comes:
the section is 0 and row is 0
although another section / row were selected.
Has someone an idea why this does not work under ios7?
Your approach to find the "enclosing" table view cell of a text field is fragile,
because is assumes a fixed view hierarchy (which seems to have changed between
iOS 6 and iOS 7).
One possible solution would be to traverse up in the view hierarchy until the table view cell is found:
UIView *view = textField;
while (view != nil && ![view isKindOfClass:[UITableViewCell class]]) {
view = [view superview];
}
EditingCell *cell = (EditingCell *)view;
A completely different, but often used method is to "tag" the text field with the row
number:
cell.textField.tag = indexPath.row; // in cellForRowAtIndexPath
and then just use that tag in the text field delegate methods.
I was finding cells the same way you were. Now I use this quick method if I have a button in a cell and know the tableview I'm in. It'll return the tableviewcell.
-(UITableViewCell*)GetCellFromTableView:(UITableView*)tableView Sender:(id)sender {
CGPoint pos = [sender convertPoint:CGPointZero toView:tableView];
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:pos];
return [tableView cellForRowAtIndexPath:indexPath];
}
Experiencing this problem in iOS 11, but not in 9 or 10, I overrode the func indexPath(for cell: UITableViewCell) -> IndexPath? method using the technique that #drexel-sharp detailed previously:
override func indexPath(for cell: UITableViewCell) -> IndexPath? {
var indexPath = super.indexPath(for: cell)
if indexPath == nil { // TODO: iOS 11 Bug?
let point = cell.convert(CGPoint.zero, to: self)
indexPath = indexPathForRow(at: point)
}
return indexPath
}

Scroll custom UITableViewCell to right above keyboard?

Currently I have a UITableView with custom cells and in each cell there is a UITextField, the problem is that sometimes the UITextField is covered by the UIKeyboard.
So right now I have the Y coordinate for the UIKeyboard and my UITableView is functioning properly with the cells.
So pretty much how can I use that Y coordinate (float), in order to scroll my UITableView to that Y coordinate plus the height of the cell in order to get it right above my UIKeyboard?
Also when I the keyboard hides, how would I reset the UITableView to its normal position that it was in?
Any advice would be appreciated!
Thanks!
CustomCell *cell = (CustomCell*)[[thetextField superview] superview];
CGRect cellRect = [cell convertRect:cell.frame toView:self.view];
float bottomCell = cellRect.origin.y - cellRect.size.height;
if (bottomCell >= keyboardY) {
NSIndexPath *indexPath = [thetableView indexPathForCell:cell];
[thetableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
One or the other of UITableView's
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
I'm guessing that control isn't getting into the if statement. Consider skipping the y-coordinate check in favor of just scrolling the table view regardless of where it is.
CustomCell *cell = (CustomCell *)[[theTextField superview] superview];
NSIndexPath *indexPath = [theTableView indexPathForCell:cell];
[theTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
OK, if you're sure it's getting called, then make sure your indexPath isn't nil, which may happen if cell isn't in the tableView or if it's not a cell.
UITableView adjust itself whenever the keyboard is displayed.
However, it won't do it if you didn't set the UITableViewCellSelectionStyle of your custom cell to UITableViewCellSelectionStyleNone.
i solved by using the below code.
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Resources