简体   繁体   中英

Handling Touch Events to Multiple Objects via Custom UITableViewCell and UITableView

I am working on a UITableView that will contain two different types of custom UITableViewCells, each cell is set to a different section of the UITable. I would like the cells to highlight to a different color upon touch, and then revert to its previous color after the touch ended. Since this doesn't follow the standard touch-highlight implementation of a standard UITableViewCell, I have added TouchesBegan() and TouchesEnd() methods to the custom cell classes to get this effect. However, the UITable will not catch any touches and therefore won't execute the didSelectRowAtIndexPath() or deselectRowAtIndexPath() methods that I need for other standard table functionality. If I comment out the TouchesBegan/TouchesEnd methods of the custom cells, the UITable will then catch the touches and call those methods. Is there a way to have the custom cells execute their touch methods as well as the UITable to execute didSelect/deselect methods upon a single touch? This my first crack at a UITable and with the expected custom functionality, I'm struggling quite a bit. I apologize if anything aside from my issues in my code is out of place, and thank you in advance for your suggestions. Here is the code for these sections below:

Touches method for Custom Cell:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [[event allTouches]anyObject];

if([touch view] == self.nameLabel) {
    CGFloat isRed = 151.0/255.0;
    CGFloat isGreen = 151.0/255.0;
    CGFloat isBlue = 151.0/255.0;

    self.nameLabel.backgroundColor = [[UIColor alloc]initWithRed:isRed green:isGreen blue:isBlue alpha:1.0];

    if(!self.currentlySelected) {

        self.currentlySelected = YES;
        self.accessoryButton.hidden = NO;
    }
    else {
        self.currentlySelected = NO;
        self.accessoryButton.hidden = YES;
    }

}
}


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches]anyObject];

if([touch view] == self.nameLabel) {
    self.nameLabel.backgroundColor = [[UIColor alloc]initWithRed:self.isRed green:self.isGreen blue:self.isBlue alpha:1.0];
}
}

For the didSelect/DeselectRow methods in the UITableViewController:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.tableView.bounds.size.width, 30.0)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];

CGFloat isRed = 84.0/255.0;
CGFloat isGreen = 84.0/255.0;
CGFloat isBlue = 84.0/255.0;

self.headerColor = [[UIColor alloc]initWithRed:isRed green:isGreen blue:isBlue alpha:0.5];


headerLabel.backgroundColor = self.headerColor;
headerLabel.opaque = NO;
headerLabel.textColor = self.textColor;
headerLabel.highlightedTextColor = [UIColor whiteColor];
headerLabel.font = [UIFont systemFontOfSize:18.0];
headerLabel.frame = CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, 30.0);

if (section == 0) {
    [headerView setBackgroundColor:self.backgroundColor];
    headerLabel.text = @"Alley";
    [headerView addSubview:headerLabel];
}
else {
    [headerView setBackgroundColor:self.backgroundColor];
    headerLabel.text = @"Bowlr";
    [headerView addSubview:headerLabel];
}
return headerView;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

if(self.lastIndexPathForAlleyCells == indexPath) {
    [self.tableView beginUpdates];
    [self.tableView deselectRowAtIndexPath:self.lastIndexPathForAlleyCells animated:NO];
    [self.tableView endUpdates];
}
if(indexPath.section == 0) {

    [self.tableView beginUpdates];
    [self.tableView deselectRowAtIndexPath:self.lastIndexPathForAlleyCells animated:NO];

    AlleyTableViewCell *cell = (AlleyTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryButton.hidden = NO;
    self.lastIndexPathForAlleyCells = indexPath;
    [self.tableView endUpdates];
}

else if(indexPath.section == 1) {
    PlayerTableViewCell *cell = (PlayerTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    [cell.accessoryButton setImage:[UIImage imageNamed:@"Checkmark.png"] forState:UIControlStateNormal];
    [cell setSelected:NO animated:NO];
}
}

Use UIGestureRecognizer instead of touch delegates .

or

Get the corresponding cell on didSelectRowAtIndexPath and do whatever you need.

If you want the selection color of the cell to be different from the default blue color simply set the backgroundView property of the cell in your cellForRowAtIndexPath method:

UIView *backgroundView = [[UIView alloc] initWithFrame:cell.frame];
backgroundView.backgroundColor = [UIColor colorWithRed:0.90f green:0.90f blue:0.90f alpha:1.00f];
cell.selectedBackgroundView = backgroundView;

The answer to this question is actually a somewhat common answer to a somewhat common problem. Considering the customization of cells to a UITable, it may not have been so apparent as to how to approach this.

It has to do with handling a touch event in the customized cell, and then sending a touch event to the parent view as well, in this case, the UITable.

Here's a link to a post that helped solve this problem:

Handling parent view touches

When you overwrite the touch methods in the child class, write out the functionality you would like to see the child execute and at the end of each method include:

[super touchesBegan: touches withEvent: event];

Do the exact same for each touch method: touchesMoved, touchesEnd, touchesCancelled.

My UITable now receives touch events and the didSelectRowAtIndexPath and deselectRowAtIndexPath methods now work because they receive touch events. I hope this helps someone else out!

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan: touches withEvent: event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ 
    [super touchesMoved: touches withEvent: event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded: touches withEvent: event];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM