简体   繁体   English

如何通过按钮操作(带有参数)从自定义UITableViewCell推送视图

[英]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 我在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. 我想使用selectedMapButton在TableViewController.m上推送视图,但是我尝试了此代码,但是有些不正确。

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

Alternate way with delegate/protocol (my best way); 委托/协议的替代方法(我最好的方法);

- Create a "CustomCellDelegate" class. -创建一个“ CustomCellDelegate”类。 (base class is NSObject) (基类是NSObject)
- Open CustomCellDelegate.h and add this code; -打开CustomCellDelegate.h并添加以下代码;

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

- Close CustomCellDelegate.h -关闭CustomCellDelegate.h
- Open CustomCell.h and add this code; -打开CustomCell.h并添加此代码;

#import "CustomCellDelegate"

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

- Close CustomCell.h -关闭CustomCell.h
- Open CustomCell.m and add code inside to UIButton action method; -打开CustomCell.m并将代码添加到UIButton动作方法中;

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

- Close CustomCell.m -关闭CustomCell.m
- Open CustomViewController.h and add this code; -打开CustomViewController.h并添加以下代码;

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

- Close CustomViewController.h and open CustomViewController.m -关闭CustomViewController.h并打开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 ;) Mertkardeşim代表ve协议endoğruçözümolacaktır;)

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. 其带有1个参数的变量将接受“发送者”,即触发操作的按钮。 Your workflow should be following: 您的工作流程应如下:

  1. Find indexPath of cell where button was clicked 查找单击按钮的单元格的indexPath
  2. Get cellSight object corresponding to that indexPath 获取对应于该indexPath的cellSight对象
  3. Fill your controller with info from cellSite object. 用cellSite对象的信息填充您的控制器。

(somewhat pseudo-)Code may look like, assuming you have array of SiteObjects: (有点伪)代码可能看起来像,假设您具有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 如何找到包含按钮的单元格的indexPath您可以在例如其他答案中找到

in your custom cell class add action for button and define a protocol(Delegate) invoke the delegate method from button action. 在您的自定义单元格类中,为按钮添加action并定义协议(委托),以从按钮操作中调用委托方法。 in cellForRowAtIndexPath set the delegate of your cell to self and implement the delegate method. cellForRowAtIndexPath ,将单元格的delegate设置为self并实现委托方法。 let me know if you've any query. 让我知道您是否有任何疑问。

I suppose the problem is in @selector(sightMapButton:cord) which is used to retrieve method's address. 我想问题出在@selector(sightMapButton:cord)中,它用于检索方法的地址。 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. 作为查找单击按钮的单元格的indexPath的替代方法:您可以继承UIButton并将其添加为属性的必需信息。 Then you can go the way Vladimir suggested, and get your cord from sender after casting it to your Button class. 然后,您可以按照弗拉基米尔(Vladimir)建议的方式进行操作,并在将其转换为Button类后从发送者那里获得电线。

Vladimir's answer works correctly and I tried this. 弗拉基米尔(Vladimir)的答案正确运行,我尝试了这个。

- (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. 这也是可行的。

  • We can use blocks to get cellIndexPath . 我们可以使用块来获取cellIndexPath。
  • Instead of using CellDelegate to call button actions Blocks will be the better option . 与其使用CellDelegate来调用按钮动作,不如使用Blocks是更好的选择。

@interface WACustomCell : UITableViewCell @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 In View控制器

-(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];

}

您应该在“自定义表”视图单元格中添加该方法。

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

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