You should find a way for the cell to signify to the controller that the button has been pressed and let the view controller (or even better, an object that the view controller creates just for the business logic).
My favorite way to do that is to define a block property on the cell for the button being tapped:
// Custom Cell Header
@property (nonatomic, copy) void(^onButtonTapped)();
@property (nonatomic, strong) NSNumber* friendId;
// Custom Cell Implementation
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.button = [UIButton new];
[self.button
addTarget:self
action:@selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside
];
[self.contentView addSubview:self.button];
}
return self;
}
- (void)buttonTapped:(id)sender
{
if (self.onButtonTapped) {
self.onButtonTapped(friendId);
}
}
// Configuring your cell
cell.textLabel.text = @"blah";
cell.friendId = theId;
cell.onButtonTapped = ^(NSNumber *friendId) {
// Do what you want with the friendId
// Most likely ask business logic object to do what it should
// with the friendId
};
Ultimately you want to keep business logic outside of the view for sure, and preferably outside of view controllers because view controllers have a tendency to fill up with code and complexity very quickly.