简体   繁体   English

通过自定义UITableViewCell和UITableView处理对多个对象的触摸事件

[英]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. 我正在处理一个UITableView,它将包含两种不同类型的自定义UITableViewCells,每个单元格设置为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. 由于这没有遵循标准UITableViewCell的标准触摸突出显示实现,因此我向自定义单元格类添加了TouchesBegan()和TouchesEnd()方法以获得此效果。 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. 但是,UITable不会捕获任何接触,因此不会执行我为其他标准表功能所需的didSelectRowAtIndexPath()或deselectRowAtIndexPath()方法。 If I comment out the TouchesBegan/TouchesEnd methods of the custom cells, the UITable will then catch the touches and call those methods. 如果我注释掉自定义单元格的TouchesBegan / TouchesEnd方法,则UITable将捕获触摸并调用这些方法。 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? 有没有一种方法可以让自定义单元格执行其触摸方法,以及让UITable在一次触摸时执行didSelect / deselect方法? This my first crack at a UITable and with the expected custom functionality, I'm struggling quite a bit. 这是我第一次在UITable上进行破解,并具有预期的自定义功能,我为此付出了很多努力。 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: 对于UITableViewController中的didSelect / DeselectRow方法:

-(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 . 使用UIGestureRecognizer代替touch delegates

or 要么

Get the corresponding cell on didSelectRowAtIndexPath and do whatever you need. didSelectRowAtIndexPath上获取相应的单元格,然后执行所需的任何操作。

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: 如果您希望单元格的选择颜色不同于默认的蓝色,只需在cellForRowAtIndexPath方法中设置单元格的backgroundView属性即可:

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. 考虑到对UITable进行单元格的自定义,关于如何实现这一点可能还不那么明显。

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. 它与处理自定义单元中的触摸事件有关,然后将触摸事件也发送到父视图(在本例中为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: 当您覆盖子类中的touch方法时,请写出您希望看到子类执行的功能,每个方法的末尾包括:

[super touchesBegan: touches withEvent: event]; [super touchesBegan:touches withEvent:event];

Do the exact same for each touch method: touchesMoved, touchesEnd, touchesCancelled. 对每种触摸方法执行完全相同的操作:touchesMoved,touchesEnd,touchesCancelled。

My UITable now receives touch events and the didSelectRowAtIndexPath and deselectRowAtIndexPath methods now work because they receive touch events. 我的UITable现在接收触摸事件,并且didSelectRowAtIndexPath和deselectRowAtIndexPath方法现在可以工作,因为它们接收触摸事件。 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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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