0
votes

I have a TableviewController : TableViewController.m , this has dynamic cells .
I have subclassed one cell(just one ) to : RegisterTableViewCell.m/.h , have a UIButton in this cell in storyboard and have created an outlet for the same in TableViewcell.m .
I have decalared a custom protocol in TableViewcell to get the click event on button in TableViewController.m . I want to do a segue on click of this button .

RegisterTableViewCell.h

@protocol CellDelegate <NSObject>
-(void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data;
@end
@property (weak,nonatomic) id<CellDelegate>delegate;
@property (assign,nonatomic) NSInteger cellIndex;
@property (weak, nonatomic) IBOutlet UIButton *PopoverAnchorButton;   

RegisterTableViewCell.m

@synthesize PopoverAnchorButton = _PopoverAnchorButton;

- (void)awakeFromNib {
    // Initialization code
    [self.PopoverAnchorButton addTarget:self action:@selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];
    //[self.PopoverAnchorButton
}
- (void)didTapButton:(id)sender{
    NSLog(@"Anchor Button Pressed");
    NSLog(@"self.delegate %d ", [self.delegate isEqual:nil]);
    NSLog(@"responds to selector  %d ", [self.delegate respondsToSelector:@selector(didClickOnCellAtIndex:withData:)]);
    if(self.delegate && [self.delegate respondsToSelector:@selector(didClickOnCellAtIndex:withData:)]){
        [self.delegate didClickOnCellAtIndex:_cellIndex withData:@"abc"];
    }

} 

TableViewController.h

    @interface SideBarTableViewController : UITableViewController <UIPopoverPresentationControllerDelegate ,CellDelegate>  

TableViewController.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *cellIdentifier = [menuItems objectAtIndex:indexPath.row];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
RegisterTableViewCell *cellreg = [[RegisterTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"register"];
cellreg.delegate = self;
cellreg.cellIndex = indexPath.row;
   return cell;
}

-(void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data
{
    NSLog(@"cell at index %ld clicked",(long)cellIndex);
}

Problem:

My didClickOnCellAtIndex func in not called in TableViewController.m . Even didTapButton func in RegisterTableViewCell.m , the 'if' condition is not executed, - "responds to selector = 0".

Also , i have just subclassed one of cells, whose instance i am getting in cellForRowAtIndexPath, but cellForRowAtIndexPath is called only once the table view is shown .

Won't the ref RegisterTableViewCell *cellreg and its property cellreg.delegate cleared by the time button on this cell is selected ?

My whole objective is to put a uibutton in some selected cells(for now say just 1) to the right end and when user clicks the cell or this button(preferably cell ), i want to do a popover presentation segue to a vc with popover arrow pointing towards the button .
For this question, my obj is to get the click event on the button in RegisterTableViewCell in TableViewController so that i can call prepareforsegue with the sender from here.

I am stuck at this . Please help.

4

4 Answers

0
votes

You aren't returning cellreg (RegisterTableViewCell) in cellForRowAtIndexPath that's why it's the problem.

0
votes

You're on the right track but there's a few things I'd recommend changing to get this working how you want.

Let's start with RegisterTableViewCell. You might find it easier to create the PopoverAnchorButton action connection from the nib by right-clicking on your button and dragging into the file, rather than awakeFromNib. Also, you'll probably want some kind of setup function which accepts things like your delegate and cell index as parameters. This will let you reuse the cell by updating the values when it is dequeued by the table.

Next, TableViewController. To get your table view to recycle cells, create a reuse identifier string (you'll use the same identifier for all cells of the same type) and call registerNib:forCellReuseIdentifier on your table view with a UINib object made with your RegisterTableViewCell, from somewhere like viewDidLoad. Then, in tableView:cellForRowAtIndexPath: you'll use dequeueReusableCellWithIdentifier to get a reusable cell. Cast it to your custom class, call the setup function I mentioned so that your delegate and index properties are correct, then return it (you don't need to make two cells like you are currently).

This should get your table recycling cells and also keeping the values appropriate for the index, with delegate intact.

0
votes

From what i understand, you want to present another view on a button press. A button that is present only on certain cells?

NSNotificationCenter may help solve your problem.

You can create a custom cell with a button added on the right end. Based on whatever condition you choose you can either hide the button or show it in the specific row of your table. You can create an IBAction for the button inside the cell's custom class and fire a notification to tell you that the button has been pressed.

- (IBAction)press:(UIButton *)sender {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"show" object:nil];
}

In your main view controller just add a observer to the notification that calls a selector to present your chosen view controller.

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showSegue) name:@"show" object:nil];
}
0
votes

The problem is:

  1. You are put the UITableViewCell *cell in your table and return it. So the tableview will show this UITableViewCell cell.

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    return cell;
    
  2. You alloc init RegisterTableViewCell, assign Delegate.. but don't use it, (do't return cellreg) so it never show up in UI and you can not interaction with this cell to trigger button and delegate.

    RegisterTableViewCell *cellreg = [[RegisterTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"register"];
    cellreg.delegate = self;
    cellreg.cellIndex = indexPath.row;
    

Fixed this by init and return RegisterTableViewCell

RegisterTableViewCell *cell = [tableView dequeueReuseWithIdentifier:@"regisID"];
if(cell == nill) {
    [tableView registerNibForCellReuserWithIdentifier:@"regisID"];//with storyboard or nib
    cell = [tableView dequeueReuseWithIdentifier:@"regisID"];
}

cell.delegate = cell;
//cell setData
return cell;