如何检测uitableViewCell上触摸的按钮并更改该按钮的BG图像

时间:2013-09-25 21:51:09

标签: iphone ios objective-c uitableview

我正在实现一个应用程序,其中我在每个单元格上都有UIButton,此按钮将特定事件添加到用户的收藏夹,然后再次单击该图像,它会从用户的收藏夹中删除该事件。我想检测用户按下该按钮的哪个单元格,并希望根据该按钮更改背景图像。

the circles in the image are uiButton 这是我的代码(我尝试过的。)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            static NSString *CellIdentifier = @"Cell";
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
            if (cell == nil) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

            }
        uncheckButton = [[UIButton alloc]init];
        appDelegate.setValue = 0;
            [uncheckButton setFrame:CGRectMake (3, 25, 30, 30)];
            [uncheckButton setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
            [uncheckButton setSelected:NO];
            [uncheckButton addTarget:self action:@selector(uncheckedButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
            [cell addSubview:uncheckButton];

        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
            return cell;

        }
-(IBAction)uncheckedButtonClicked:(id)sender
{

    if(appDelegate.setValue ==0)
    {
        appDelegate.setValue =1;
        [uncheckButton addTarget:self action:@selector(uncheckedButtonClicked:) forControlEvents: UIControlEventTouchUpInside];
        [uncheckButton setFrame:CGRectMake(3, 25, 30, 30)];
        [uncheckButton setImage:[UIImage imageNamed:@"checked_red.png"] forState:UIControlStateNormal];


        Reachability *reachability = [Reachability reachabilityForInternetConnection] ;
        NetworkStatus netWorkStatus = [reachability currentReachabilityStatus] ;
        if (netWorkStatus == ReachableViaWWAN || netWorkStatus == ReachableViaWiFi)
        {

                [NSThread detachNewThreadSelector:@selector(threadStartAnimating:) toTarget:self withObject:nil];
                NSLog(@"%@",appDelegate.user_id);
                Communication *objCommunication = [[Communication alloc] init];
                objCommunication.delegate = self;
                [objCommunication setServiceFor:@"My_Agenda_add"];

                NSURL *url =  [NSURL URLWithString: [NSString stringWithFormat:@"%@/api/join_session",BASE_URL]];
                NSString *body = [ NSString stringWithFormat:@"user_id=%@&session_id=%@",[appDelegate.user_id objectAtIndex:0],[[self.globalSessionArray valueForKey:@"_id"]valueForKey:@"$id"]];
                [objCommunication makeAsynchronousRequestWithUrl:url withBodyString:body andWithMethod:@"POST"];objCommunication = nil;

        }

        else
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:app_name message:network_connectivity delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        }
    }

    else if(appDelegate.setValue)
    {
        appDelegate.setValue = 0;
        [uncheckButton addTarget:self action:@selector(uncheckedButtonClicked:) forControlEvents: UIControlEventTouchUpInside];
        [uncheckButton setFrame:CGRectMake(3, 25, 30, 30)];
        [uncheckButton setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];

        Reachability *reachability = [Reachability reachabilityForInternetConnection] ;
        NetworkStatus netWorkStatus = [reachability currentReachabilityStatus] ;
        if (netWorkStatus == ReachableViaWWAN || netWorkStatus == ReachableViaWiFi)
        {
                [NSThread detachNewThreadSelector:@selector(threadStartAnimating:) toTarget:self withObject:nil];
                NSLog(@"%@",appDelegate.user_id);
                Communication *objCommunication = [[Communication alloc] init];
                objCommunication.delegate = self;
                [objCommunication setServiceFor:@"My_Agenda_remove"];
                NSURL *url =  [NSURL URLWithString: [NSString stringWithFormat:@"%@/api/unjoin_session",BASE_URL]];
                NSString *body = [ NSString stringWithFormat:@"user_id=%@&session_id=%@",[appDelegate.user_id objectAtIndex:0],[[self.globalSessionArray valueForKey:@"_id"]valueForKey:@"$id"]];
                [objCommunication makeAsynchronousRequestWithUrl:url withBodyString:body andWithMethod:@"POST"];objCommunication = nil;

        }

        else
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:app_name message:network_connectivity delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        }
    }



    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0] ;
    NSLog(@"%@",indexPath);

    UITableViewCell* cell = [self.agendaTableView cellForRowAtIndexPath:indexPath];
    [cell addSubview:uncheckButton];
    [self.agendaTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

}

3 个答案:

答案 0 :(得分:2)

最简洁的方法是创建一个处理uncheckButtonClicked操作的UITableViewCell子类。自我将继续成为目标,因此它始终由正确的细胞处理。

另一种选择是在视图控制器级别上拥有一个跟踪UIButton / UITableViewCell对的NSDictionary。您可以通过这种方式查询字典以获取相应的UITableViewCell。

另一种选择是查询UIButton的超级视图,它将是正确的UITableViewCell。

-(IBAction)uncheckedButtonClicked:(id)sender
{
    UIButton *button = (UIButton *)sender;
    UITableViewCell *cell = (UITableViewCell *)[button superview];
    ...
}

答案 1 :(得分:1)

此代码存在以下几个问题:

  1. 每次更新时,您都会向单元格添加一个新的按钮子视图,这会导致泄漏,因为您没有重复使用旧按钮。相反,您应该只在初始化代码中添加一次按钮,并为其提供一个标记,您可以在获取重用单元格时使用该标记来访问该按钮。

  2. 根据您的说明,您希望同时选中已检查和未选中的案例,但似乎只有一个案例。要解决此问题,您可以在cellForRowAtIndexPath中使用if / else语句,根据模型状态将按钮的图像设置为正确的。

  3. 百分之一的答案有一个很好的建议,即使用某种模型来跟踪按钮来自哪个单元格。 NSMutableDictionary在这里运行良好。我建议不要抓住按钮的超视图来获取它来自的单元格。试图从视图中获取模型是不好的做法,可能导致问题。

    示例代码:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
    
        UIButton *checkButton;
        static const NSInteger kCheckButtonTag = 1;
        if (cell == nil) 
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
            [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
            checkButton = [[UIButton alloc] init];
            [checkButton setFrame:CGRectMake (3, 25, 30, 30)];
            [checkButton addTarget:self action:@selector(checkedButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
            checkButton.tag = kCheckButtonTag;
            [cell.contentView addSubview:uncheckButton];
        }
        else
        {
            checkButton = (UIButton *)[cell.contentView viewWithTag:kCheckButtonTag];
        }
    
    
        if(model is unchecked) // replace with correct condition
            [checkButton setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
        else
            [checkButton setImage:CHECKED_IMAGE_GOES_HERE forState:UIControlStateNormal]; // replace with your checked image
    
        // assuming buttonToModelDictionary is an initialized ivar NSMutableDictionary
        buttonToModelDictionary[checkButton] = YOUR_MODEL_OBJECT_GOES_HERE;
        return cell;
    
    }
    
    - (void) checkButtonClicked:(id)sender
    {
        (UIButton *)button = (UIButton *)sender;
        YOUR_MODEL_OBJECT_GOES_HERE = buttonToModelDictionary[button];
    
        // do whatever you need to update the model here, then call [self.tableView reloadData] OR [self.tableView reloadRowsAtIndexPaths...] if you can gather the row using the model object, which you should be able to do.
    }
    

答案 2 :(得分:1)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"MyFeedCell";
NotificationCellView *cell = (NotificationCellView *) [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NotificationCellView" owner:self options:nil];
    for (id currentObject in topLevelObjects) {
        if ([currentObject isKindOfClass:[UITableViewCell class]]) {
            cell = (NotificationCellView *)currentObject;
            break;
        }
    }
}
zNotification *notifiItem=(zNotification *)[notificationData objectAtIndex:indexPath.row];

cell.Name.text = notifiItem.userName;
cell.clipImage.hidden= !notifiItem.hasFile;
[cell.clipImage addTarget:self action:@selector(viewFiles:) forControlEvents:
 UIControlEventTouchUpInside];
cell.clipImage.tag=indexPath.row+100000;
cell.leftImg.hidden=YES;
cell.left.hidden=YES;
cell.centerImg.hidden=YES;
cell.center.hidden=YES;
//cell.right.hidden=YES;
//cell.rightImg.hidden=YES;
[cell.right addTarget:self action:@selector(wall_Followup:) forControlEvents:UIControlEventTouchUpInside];
cell.right.tag = 1100+indexPath.row;
if(notifiItem.Type==0)
{

    [cell.right setTitle:@"Reply" forState:UIControlStateNormal];
}else
{

    [cell.center setTitle:@"Followup" forState:UIControlStateNormal];
}
switch (notifiItem.Type) {
    case 0:
        cell.tag.text=@"New Followup";
        [cell.userImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://graph.facebook.com/%@/picture",notifiItem.userImg]]
                       placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
        break;
    case 1:
        cell.tag.text=@"New Task";
        [cell.userImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://graph.facebook.com/%@/picture",notifiItem.userImg]]
                       placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
        cell.centerImg.hidden=NO;
        cell.center.hidden=NO;
        [cell.center setTitle:@"Done" forState:UIControlStateNormal];
        [cell.centerImg setImage:[UIImage imageNamed:@"Done.png"]];
        [cell.center addTarget:self action:@selector(doneTask:) forControlEvents:UIControlEventTouchUpInside];
        cell.center.tag=1200+indexPath.row;
        break;
    case 2:
        cell.tag.text=@"New Member";
        [cell.userImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://graph.facebook.com/%@/picture",notifiItem.userImg]]
                       placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
        break;
    case 3:
        cell.tag.text=@"Task Reminder";
        [cell.userImage setImage:[UIImage imageNamed:@"attention.png"]];
        cell.Name.text = @"Attention";
        cell.centerImg.hidden=NO;
        cell.center.hidden=NO;
        [cell.center setTitle:@"Done" forState:UIControlStateNormal];
        [cell.centerImg setImage:[UIImage imageNamed:@"Done.png"]];
        [cell.center addTarget:self action:@selector(doneTask:) forControlEvents:UIControlEventTouchUpInside];
        cell.center.tag=1200+indexPath.row;
        break;
    case 4:
        cell.tag.text=@"New File";
        [cell.userImage setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://graph.facebook.com/%@/picture",notifiItem.userImg]]
                       placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
        break;
    case 5:
        cell.tag.text=@"Task Completed";
        [cell.userImage setImage:[UIImage imageNamed:@"attention.png"]];
        cell.Name.text = @"Attention";
        cell.centerImg.hidden=NO;
        cell.center.hidden=NO;
        [cell.center setTitle:@"Delete" forState:UIControlStateNormal];
        [cell.centerImg setImage:[UIImage imageNamed:@"Delete.png"]];
        [cell.center addTarget:self action:@selector(deleteTask:) forControlEvents:UIControlEventTouchUpInside];
        /*cell.leftImg.hidden=NO;
        cell.left.hidden=NO;
        [cell.left setTitle:@"Reassign" forState:UIControlStateNormal];
        [cell.leftImg setImage:[UIImage imageNamed:@"re_Asign2.png"]];
        [cell.left addTarget:self action:@selector(reAssign:) forControlEvents:UIControlEventTouchUpInside];*/
        break;
    case 6:
        cell.tag.text=@"Task Deleted";
        [cell.userImage setImage:[UIImage imageNamed:@"attention.png"]];
        cell.Name.text = @"Attention";
        break;
    case 7:
        cell.tag.text=@"Group Deleted";
        [cell.userImage setImage:[UIImage imageNamed:@"attention.png"]];
        cell.Name.text = @"Attention";
        break;
    case 8:
        cell.tag.text=@"Group Invitation";
        [cell.userImage setImage:[UIImage imageNamed:@"groupInv.png"]];
        cell.Name.text = @"Invitation";
        cell.centerImg.hidden=NO;
        cell.center.hidden=NO;
        [cell.center setTitle:@"Join" forState:UIControlStateNormal];
        cell.center.tag = 1000+indexPath.row;
        [cell.centerImg setImage:[UIImage imageNamed:@"join.png"]];
        [cell.center addTarget:self action:@selector(joinGroup:) forControlEvents:UIControlEventTouchUpInside];
        break;
    default:
        break;
}


cell.Details.text=notifiItem.MSG;
cell.date.text=notifiItem.date;//[NSString stringWithFormat:@"%d",notifiItem.Type];//notifiItem.date;

cell.groupName.text = notifiItem.group.title;
cell.accessoryType = UITableViewCellAccessoryNone;
if (!notifiItem.isChecked) {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    float whiteFloat[4] = {1.0, 0.7, 0.7, 1.0};
    CGColorRef white = CGColorCreate(colorSpace, whiteFloat);
    cell.detailBox.layer.shadowColor=[[UIColor redColor] CGColor];
    cell.shade.layer.backgroundColor=white;
}else
{
    //CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    //float whiteFloat[4] = {0.7, 0.7, 0.7, 1.0};
    //CGColorRef white = CGColorCreate(colorSpace, whiteFloat);
    cell.detailBox.layer.shadowColor=[[UIColor blackColor] CGColor];
}
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}


    - (IBAction)doneTask:(id)sender
    {
    UIButton *b=(UIButton *)sender;
    NSLog(@"%d",b.tag);
    [b setImage:[UIImage imageNamed:@"Delete.png"] forState:UIControlStateNormal];
   zNotification *n=notificationData[b.tag-1200];
}

喂 这是我的一个项目的快速示例 这里是重要的案例3:代码是复杂的 但你可以使用按钮标签来指定单元格1200的行号我添加了b / c 在同一个单元格中有多个按钮,因此按钮A 1200和按钮B 1300以及我打电话时 函数我相应地删除1200或1300和doneTask函数简单地将按钮转换为UIButton并从标签获取行号并分配背景图像

Screen Shot