Mert Karabulut
Mert Karabulut

Reputation: 63

How to push a view from custom UITableViewCell with button action (with parameters)

I added a button on the custom cell. It pushes a view. I created property for button on CustomTableViewCell.h

@property (weak, nonatomic) IBOutlet UIButton *selectedMapButton;

I want to use selectedMapButton for push a view on TableViewController.m I tried this code, but something is not right.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cord = cellSight[@"S_Coodinates"];

    [cell.selectedMapButton addTarget:self action:@selector(sightMapButton:cord) forControlEvents:UIControlEventTouchUpInside];

    //When I call sightMapButton method. It gives an error

    return cell;
}

- (void)sightMapButton: (NSString *)withCoordinates
{
    TOCGSightseeingMapKitViewController *mapKitController = [[TOCGSightseeingMapKitViewController alloc] init];
    mapKitController.sightCoordinates = withCoordinates;

    [self.navigationController pushViewController:mapKitController animated:YES];
}

How can I solve it? Thanks.

Upvotes: 1

Views: 1488

Answers (7)

Jayaprada
Jayaprada

Reputation: 954

  • We can use blocks to get cellIndexPath .
  • Instead of using CellDelegate to call button actions Blocks will be the better option .

@interface WACustomCell : UITableViewCell

@property(readwrite,copy)void (^cellCallBackMethod)(NSInteger rowIndexPath);

-(IBAction)buttonTappedFromCell:(id)sender;

@end
 @implementation WACustomCell

 @synthesize cellCallBackMethod;


     -(IBAction)buttonTappedFromCell:(id)sender{

 self.cellCallBackMethod(0);

 //any value can be given as we will retrive this value from CellForRowAtIndex method


 }

In View Controller

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


cel = ....
cell.cellCallBackMethod = ^(NSInteger cellIndex){

    [self cellButtonTappedFromCellWithIndex:cellIndex];
};

return cell;
}
-(void)cellButtonTappedFromCellWithIndex:(NSInteger )cellIndex{


SiteObject cellSight = sitesArray[cellIndex];
TOCGSightseeingMapKitViewController *mapKitController = [[TOCGSightseeingMapKitViewController alloc] init];
mapKitController.sightCoordinates = cellSight[@"S_Coodinates"];

    [self.navigationController pushViewController:mapKitController animated:YES];

}

Upvotes: 0

serdaryillar
serdaryillar

Reputation: 413

Alternate way with delegate/protocol (my best way);

- Create a "CustomCellDelegate" class. (base class is NSObject)
- Open CustomCellDelegate.h and add this code;

@protocol CustomCellDelegate <NSObject>
   - (void) uiTapButtonWithParameter:(NSString *)parameter;    
@end

- Close CustomCellDelegate.h
- Open CustomCell.h and add this code;

#import "CustomCellDelegate"

@interface CustomCell : UITableViewCell
@property (nonatomic) id <CustomCellDelegate> delegate;

- Close CustomCell.h
- Open CustomCell.m and add code inside to UIButton action method;

[_delegate uiTapButtonWithParameter:@"hello world!"];

- Close CustomCell.m
- Open CustomViewController.h and add this code;

@interface CustomViewController : UIViewController <UITableViewDelegate,   UITableViewDataSource, CategoryItemsCellDelegate>

- Close CustomViewController.h and open CustomViewController.m
- Add this code;

- ( NSInteger )tableView:( UITableView * )tableView numberOfRowsInSection:( NSInteger    )section; {
    return 20;
}

- ( UITableViewCell * )tableView:( UITableView * )tableView cellForRowAtIndexPath:( NSIndexPath * )indexPath; {

  CategoryItemsCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];

  cell.delegate = self;

  return cell;
}

- (void) uiTapButtonWithParameter:(NSString *)parameter{
     NSLog(@"%@",parameter)
 }

Mert kardeşim delegate ve protocol en doğru çözüm olacaktır ;)

Upvotes: 3

Mert Karabulut
Mert Karabulut

Reputation: 63

Vladimir's answer works correctly and I tried this.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.selectedMapButton.tag = indexPath.row;

    [cell.selectedMapButton addTarget:self action:@selector(sightMapButton:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)sightMapButton:(UIButton *)sender
{
    TOCGSightseeingMapKitViewController *mapKitController = [[TOCGSightseeingMapKitViewController alloc] init];
    mapKitController.sightCoordinate = self.sights[sender.tag][@"S_Coordinates"];
    [self.navigationController pushViewController:mapKitController animated:YES];
}

It is also works.

Upvotes: 0

Bharat
Bharat

Reputation: 3007

in your custom cell class add action for button and define a protocol(Delegate) invoke the delegate method from button action. in cellForRowAtIndexPath set the delegate of your cell to self and implement the delegate method. let me know if you've any query.

Upvotes: 1

user2260054
user2260054

Reputation: 522

I suppose the problem is in @selector(sightMapButton:cord) which is used to retrieve method's address. Most likely you are not allowed to pass arguments here.

As an alternative to finding the indexPath of cell where button was clicked: You can subclass UIButton and add required information to it as a property. Then you can go the way Vladimir suggested, and get your cord from sender after casting it to your Button class.

Upvotes: 0

Vladimir
Vladimir

Reputation: 170839

You cannot specify your own parameters to button action handler. Its variant with 1 parameter will accept "sender", that is button that triggered the action. Your workflow should be following:

  1. Find indexPath of cell where button was clicked
  2. Get cellSight object corresponding to that indexPath
  3. Fill your controller with info from cellSite object.

(somewhat pseudo-)Code may look like, assuming you have array of SiteObjects:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell = ...  // create/init cell somehow

    [cell.selectedMapButton addTarget:self action:@selector(sightMapButton:) forControlEvents:UIControlEventTouchUpInside];

    return cell;
}

- (void)sightMapButton: (UIButton *)sender
{
    NSIndexPath *indexPath = ... // Find indexPath of button
    SiteObject cellSight = sitesArray[indexPath.row];
    TOCGSightseeingMapKitViewController *mapKitController = [[TOCGSightseeingMapKitViewController alloc] init];
    mapKitController.sightCoordinates = cellSight[@"S_Coodinates"];

    [self.navigationController pushViewController:mapKitController animated:YES];
}

How to find indexPath of cell containing button you can find for example in my other answer

Upvotes: 1

yoshiiiiiiii
yoshiiiiiiii

Reputation: 944

You should add the method in Custom table view cell.

Upvotes: -1

Related Questions