0

I have a tricky problem here.

A UITextView is a subview of `UITableViewCell.

The UITextView receives touch event and tableView: didSelectRowAtIndexPath: isn't invoked.

I know I can get the tableView's event if I set userInteraction:NO to UITextView. However, the UITextView's content is NSAttributedString and the string has NSLinkAttributeName attribute. If I set userInteraction to false, I can't get the textView:shouldInteractWithURL:inRange:.

Is there any good way to be enabled both events together?

Ryan
  • 4,799
  • 1
  • 29
  • 56
  • Set your `UITextView` property `editable` to `FALSE` and its `userInteraction` to `TRUE`? – Larme Feb 16 '15 at 10:16
  • do you have section in this tableView? or is it all in one section? – YYfim Feb 16 '15 at 10:22
  • @Larme `UITextView` shouldn't be `editable` in my case. – Ryan Feb 16 '15 at 10:27
  • @YuviGr I have 3~5 sections in case of data. – Ryan Feb 16 '15 at 10:28
  • (http://stackoverflow.com/questions/28472073/can-i-get-the-position-of-elements-in-nsattributedstring/28472900#28472900) check this link it will help you – Pallavi Ligade Feb 16 '15 at 10:54
  • 1
    In a nutshell, no. The text field is the responder to the users touch and so invalidates the tableView. Why can't you simply call didSelectRowAtIndexPath yourself if you are relying on code in there as well? – Daniel Galasko Feb 16 '15 at 12:58

2 Answers2

1

You can create a subClass of the UITextView and add two variables

@property (nonatomic) NSInteger row;
@property (nonatomic) NSInteger section;

that will hold the section number and row number. With these properties you can use delegation/KVO to the tell the viewController that a cell in (row:x & section:y) was selected.

EDIT

This edit is updated from @Daniel Galasko comment.

A better way to solve this is using the method indexPathForRowAtPoint: like so:

set the viewController to be the UITextView's delegate, and in the dekegate method

- (void)textViewDidBeginEditing:(UITextView *)textView
{
   CGPoint position = [textView convertPoint:CGPointZero toView: <yourtableView> ];
   NSIndexPath *indexPath = [<your tableView> indexPathForRowAtPoint: position];
} 
YYfim
  • 1,402
  • 1
  • 9
  • 24
  • Thats silly, imagine you had multiple different views in a cell. you would have to do this for every view. Why not use the indexPathForRowAtPoint method... – Daniel Galasko Feb 16 '15 at 12:41
  • where would you use this method?! – YYfim Feb 16 '15 at 12:49
  • see my answer here http://stackoverflow.com/questions/9577392/uitextfield-subview-of-uitableviewcell-get-indexpath-of-cell/27938042#27938042 once you have the textView you can easily get its index path assuming you also have access to the table view – Daniel Galasko Feb 16 '15 at 12:51
  • yes i can see how that could work thanks ill update the answer – YYfim Feb 16 '15 at 12:56
0

Since you are trying to get a cell why don't user superview ?

For instance, when you select your textBox, you can say something like

- (void)textViewDidBeginEditing:(UITextView *)textView
{
   UITableViewCell *cell = (UITableViewCell*)textView.superview.superview;
}

Note that you need it twice, once for content view and next for tableview cell.

Here is reference for UITableView hierarchy: http://www.curiousfind.com/blog/646

Also, take care when you are dealing with ios8 since I think they added additional layer. Because of that you could do something like this:

-(UITableViewCell*)getCellForTextView:(UIView*)searchForView
{
    if(search isKindOfClass:[UITableViewCell class]){
        return search;
    }
    if(!search)
       return NULL;
    return [self getCellForTextView:search.superview];
}

and in you function you can do:

- (void)textViewDidBeginEditing:(UITextView *)textView
    {
       UITableViewCell *cell = [self getCellForTextView:textView];
       if(cell) 
       {
          //do stuff
       }
       else 
       {
            //it is null! handle this somehow
       }
    }
Miknash
  • 7,888
  • 3
  • 34
  • 46