简体   繁体   English

Objective-C自定义表格单元格按钮

[英]Objective-c custom table cell buttons

I'm trying to implement a table view where all rows have 2 buttons which then do something with the data at the index row they are on. 我正在尝试实现一个表视图,其中所有行都有2个按钮,然后对它们所在的索引行上的数据进行处理。

here is what I have so far: 这是我到目前为止所拥有的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"NotificationCell";
    NotificationCell *cell = (NotificationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (cell == nil) {
        cell = [[NotificationCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NotificationObject *notification = nil;
    notification = [_notificationArray objectAtIndex:indexPath.row];



    cell.profileImage.image = notification.profileImage;
    cell.profileImage.layer.cornerRadius = cell.profileImage.frame.size.height /2;
    cell.profileImage.layer.masksToBounds = YES;
    cell.profileImage.layer.borderWidth = 0;
    cell.detailTextView.text = notification.action;

    UIButton *denyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    //set the position of the button
    denyButton.frame = CGRectMake(cell.frame.origin.x + 285, cell.frame.origin.y + 20, 23, 23);
    [denyButton setBackgroundImage:[UIImage imageNamed:@"DenyRequest.png"] forState:UIControlStateNormal];
    [denyButton addTarget:self action:@selector(denyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    denyButton.backgroundColor= [UIColor clearColor];
    [cell.contentView addSubview:denyButton];

    acceptButton.frame = CGRectMake(cell.frame.origin.x + 240, cell.frame.origin.y + 20, 23, 23);
    [acceptButton setBackgroundImage:[UIImage imageNamed:@"AcceptRequest.png"] forState:UIControlStateNormal];
    [acceptButton addTarget:self action:@selector(AcceptButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    acceptButton.backgroundColor= [UIColor clearColor];
    [cell.contentView addSubview:acceptButton];

    return cell;
}

-(void)denyButtonPressed:(id)sender{

    NSLog(@"buttonPressedDeny");


    }

-(void)AcceptButtonPressed:(id)sender{

    NSLog(@"buttonPressedAccept");


}

However I am not sure how to find out which index row the selected button was pressed so that I can get the relevant data. 但是我不确定如何找出所选按钮被按下到哪个索引行,以便获得相关数据。

The simplest solution is to assign a tag to each button. 最简单的解决方案是为每个按钮分配一个标签。 For example: 例如:

denyButton.tag = 1000 + indexPath.row;

Then on denyButtonPressed: 然后在denyButtonPressed上:

-(void)denyButtonPressed:(id)sender{
     UIButton *b = (UIButton *)sender;
     NSInteger row = b.tag - 1000;
     NSLog(@"buttonPressedDeny: %d", row);
}

The variable row will hold the index path row where the button was pressed. 变量行将保存按下按钮的索引路径行。 The addition of 1000 is to avoid collision with other views you may already have. 增加1000是为了避免与您可能已经拥有的其他视图冲突。

Let me emphasize that this is the SIMPLEST solution but not the most friendly from a design/architecture point of view. 让我强调一下,这是SIMPLEST解决方案,但从设计/体系结构的角度来看并不是最友好的解决方案。

A more elaborate solution could be to have the buttons as part of NotificationCell, have NotificationCell be the delegate for those buttons, and create a protocol that allows your view controller to be the delegate of each NotificationCell. 一个更复杂的解决方案可能是将按钮作为NotificationCell的一部分,让NotificationCell作为这些按钮的委托,并创建一个协议,使您的视图控制器成为每个NotificationCell的委托。 Then when the button is pressed, it will be handled by NotificationCell, which will pass whatever object is needed to your view controller. 然后,当按下按钮时,它将由NotificationCell处理,NotificationCell将把所需的任何对象传递给视图控制器。

For example, create the following protocol in NotificationCell.h 例如,在NotificationCell.h中创建以下协议

@protocol NotificationCellDelegate
- (void)denyActionForNotificationObject:(NotificationObject *)notificationObject;
- (void)acceptActionForNotificationObject:(NotificationObject *)notificationObject;
@end

Also add NotificationCell add a property to hold a notification and a delegate: 还添加NotificationCell添加一个属性来保存通知和委托:

@property (nonatomic, strong) NotificationObject *notificationObject;
@property (nonatomic, strong) id<NotificationCellDelegate> delegate;

Create a method awakeFromNib (if you are using storyboards) 创建方法awakeFromNib(如果使用情节提要)

- (void)awakeFromNib {
    [super awakeFromNib];
    UIButton *denyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    //set the position of the button
    denyButton.frame = CGRectMake(self.contentView.frame.origin.x + 285, self.contentView.frame.origin.y + 20, 23, 23);
    [denyButton setBackgroundImage:[UIImage imageNamed:@"DenyRequest.png"] forState:UIControlStateNormal];
    [denyButton addTarget:self action:@selector(denyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    denyButton.backgroundColor= [UIColor clearColor];
    [self.contentView addSubview:denyButton];

    acceptButton.frame = CGRectMake(self.contentView.frame.origin.x + 240, self.contentView.frame.origin.y + 20, 23, 23);
    [acceptButton setBackgroundImage:[UIImage imageNamed:@"AcceptRequest.png"] forState:UIControlStateNormal];
    [acceptButton addTarget:self action:@selector(AcceptButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    acceptButton.backgroundColor= [UIColor clearColor];
    [cell.contentView addSubview:acceptButton];
}

Implement the selectors you declared: 实现您声明的选择器:

- (void)denyButtonPressed:(id)sender {
    if (_delegate) {
        [_delegate denyActionForNotificationObject:_notificationObject];
     }
}

- (void)AcceptButtonPressed:(id)sender {
    if (_delegate) {
        [_delegate acceptActionForNotificationObject:_notificationObject];
     }
}

Then in your cellForRowAtIndexPath in your view controller add: 然后在您的视图控制器的cellForRowAtIndexPath中添加:

cell.notificationObject = notificationObject;
cell.delegate = self;

Also in your view controller, implement the protocol: 同样在您的视图控制器中,实现协议:

- (void)denyActionForNotificationObject:(NotificationObject *)notificationObject {
    // Do something with the notification object
}
- (void)acceptActionForNotificationObject:(NotificationObject *)notificationObject {
    // Do something with the notification object
}

I have not tested this in XCode, my apologies if it doesn't compile 我没有在XCode中测试过,如果无法编译,我深表歉意

Why not work backwards through the view hierarchy and check the button's superview , which should be the content view of the table view cell. 为什么不向后浏览视图层次结构并检查按钮的superview ,它应该是表视图单元格的内容视图。 Whose superview should be the cell? 谁的superview应该是牢房?

-(void)denyButtonPressed:(id)sender{
     UIButton *button = (UIButton *)sender;
     UIView *contentView = button.superview;
     UITableViewCell *cell = contentView.superview;
     NSIndexPath * indexPath = self.tableView indexPathForCell:cell];
     NSLog(@"row containing button: %d", indexPath.row);
}

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

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