Search code examples
iosobjective-cuitableviewuiscrollview

How to call didSelectRowAtIndexPath from subclassed UITableViewCell


I have a UITableView that I am using to show data that requiers me to have a much wider cell than the iPhone screenWidth.

Because of this I have created a subclassed UITableViewCell that contains a subclassed UIScrollView. This is what my code looks like.

TableView.h

@property (strong, nonatomic) CustomCell *cell;

TableView.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cellDictionary = [xmlMArray objectAtIndex:indexPath.row];
    static NSString *CellIdentifier = @"Cell";

    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    // Configure the cell.
    cell.selectionStyle = UITableViewCellSelectionStyleGray;

    cell.itemsDictionary = cellDictionary;
    cell.currentIndex = indexPath;

    cellDictionary = nil;
    [cell drawCell];

    return cell;
}

In the above method you can see I am calling a custom UITableViewCell that I have created.

CustomCell.h

@property (strong, nonatomic) NSDictionary *itemsDictionary;
@property (strong, nonatomic) MyScrollView *scrollCell;
@property (strong, nonatomic) NSIndexPath *currentIndex;

- (void)drawCell;

CustomCell.m

- (void)drawCell
{
    scrollCell = [[MyScrollView alloc] init];
    scrollCell.itemsDictionary = itemsDictionary;
    [scrollCell drawCell];
    scrollCell.backgroundColor = [UIColor whiteColor];
    scrollCell.frame = CGRectMake(0.0, 0.0, ScreenWidth, 45.0);

    [[self contentView] addSubview:scrollCell];
}

In the above drawCell method I am calling a custom scrollView

MyScrollView.m

- (void)drawCell
{
    bgGray = NO;
    fNameString = [[UILabel alloc] init];
    fNameString.backgroundColor = [UIColor clearColor];
    fNameString.frame = CGRectMake(15.0, 0.5, 70.0, 40.0);
    fNameString.text = [itemsDictionary objectForKey:@"fName"];

    lNameString = [[UILabel alloc] init];
    lNameString.backgroundColor = [UIColor clearColor];
    lNameString.frame = CGRectMake(105.0, 0.5, 95.0, 40.0);
    lNameString.text = [itemsDictionary objectForKey:@"lName"];

    addressString = [[UILabel alloc] init];
    addressString.backgroundColor = [UIColor clearColor];
    addressString.frame = CGRectMake(220.0, 10.5, addressString.frame.size.width, 50.0);
    addressString.text = [NSString stringWithFormat:@"Address: %@: %@",[itemsDictionary objectForKey:@"aNumber"] ,[itemsDictionary objectForKey:@"aString"]];
    [addressString sizeToFit];

    [self setContentSize:(CGSizeMake((220.0 + addressString.frame.size.width)+15, 45.0))];

    [self addSubview:fNameString];
    [self addSubview:lNameString];
    [self addSubview:addressString];
}

The above method draws the scrollview that is then passed onto the CustomCell, everything works fine and displays correctly, below is the method I am using to detect a touch on the cusome scroll view its in the same class as the method above and looks like this.

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
{
    NSLog(@"touch scroll");
    // If not dragging, send event to next responder
    if (!self.dragging) {
        // touch detected...
        //How can I now call didSelectRow from TableView?
    } else {
        [super touchesEnded: touches withEvent: event];
    }
}

So my question is this, how can I use this touchEnded method to call didSelectRowFromIndexPath method that is in the original TableView class? Or is there a better way to do this than what I am currently doing?

Note: the reason I have had to use these subclasses is because the UIScrollView is covering the UITableViewCell selection function, so I had to subclass the scrollview to intercept the touch event now I'm hoping I can call the original tableview selection method with your help.


Solution

  • How about calling the delegate function using the following code:

    [yourTableView.delegate tableView:tableView didSelectRowAtIndexPath:aIndexPath];
    

    In your subclassed cell store a weak reference to your tableview and indexPath.

    Another solution is to loop through your cell's superview until you find the tableview. This has its cons though, Apple may one day change the way the view hierarchy structured which will break the code as they did from iOS6 to iOS7 by wrapping another layer around some views...