简体   繁体   中英

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.

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:

-(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.

Let me emphasize that this is the SIMPLEST solution but not the most friendly from a design/architecture point of view.

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. Then when the button is pressed, it will be handled by NotificationCell, which will pass whatever object is needed to your view controller.

For example, create the following protocol in 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:

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

Create a method awakeFromNib (if you are using storyboards)

- (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:

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

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. Whose superview should be the cell?

-(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);
}

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