将按钮选择器从单元格传递到View Controller的最佳方法

时间:2014-06-26 16:05:34

标签: ios objective-c uitableview ios7

我已经实现了Swipeable单元的自定义实现。部分基于此: - https://github.com/mbigatti/BMXSwipableCell

当设置了basementView时(这是将按钮保持在单元格内容视图之下的视图),我们添加两个按钮,如下所示:

    UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
    deleteButton.backgroundColor = [UIColor colorWithRed:0.925 green:0.941 blue:0.945 alpha:1.000];
    deleteButton.frame = CGRectMake(x + cellHeight, 0, cellHeight, cellHeight);
    [deleteButton setTitle: @"Test" forState: UIControlStateNormal];
    [deleteButton addTarget: self
                     action: @selector(userPressedCallBasementButton:)
           forControlEvents: UIControlEventTouchUpInside];  

注意:这是从configureCell方法调用的,其中数据模型传递给tableviewcell子类以配置该单元格。该单元格仅具有IBOutlets属性。

方法userPressedCallBasementButton当前在单元子类中实现,因为目标是self。但是,我需要的数据是在View控制器上,即表数据数组。

问题:如何为此按钮设置视图控制器的目标并在视图控制器上设置方法?此外,我如何获得在视图控制器方法中使用的特定单元格引用/ indexPath?

2 个答案:

答案 0 :(得分:2)

首先,对于按钮的indexPath,我总是将UIButton子类化,并为其赋予indexPath属性,可以在创建单元格时将其设置为按钮。< / p>

<强> IndexedButton.h

@interface IndexedButton : UIButton

@property (nonatomic, retain) NSIndexPath *indexPath;

@end

<强> SomeTableViewController.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // create your cell...
    cell.deleteButton.indexPath = indexPath;
    // ...
    return cell;
}

至于通知您的主视图控制器,如果您无法将indexedButton直接发送给您查看操作,您可以启动NSNotification或设置代理协议,以较为者是你的偏好。代表/通知将发送前面提到的indexPath告诉您的主视图按下了哪个按钮。


代表设置:

<强> CustomCell.h

#import <UIKit/UIKit.h>

@protocol CustomCellDelegate;

@interface CustomCell : UITableViewCell
// whatever else you have in your header goes here
@property (nonatomic, weak) id<CustomCellDelegate> delegate;
@end

@protocol CustomCellDelegate <NSObject>
// other delegate methods go here for other buttons that need to notify main view
- (void)callBasementButtonTapped:(NSIndexPath *)indexPath;
@end

<强> CustomCell.m

//...
- (void)userPressedCallBasementButton:(id)sender
{
    NSIndexPath *indexPath = ((IndexedButton *)sender).indexPath;
    id<CustomCellDelegate> strongDelegate = self.delegate;

    if ([strongDelegate respondsToSelector:@selector(callBasementButtonTapped:)])
    {
        [strongDelegate callBasementButtonTapped:indexPath];
    }
}

同时,回到 SomeTableViewController.m

@interface SomeTableViewController () <CustomCellDelegate>

//...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // create your cell...
    cell.deleteButton.indexPath = indexPath;
    cell.delegate = self;
    // ...
    return cell;
}

//...

- (void)callBasementButtonTapped:(NSIndexPath *)indexPath
{
    // do whatever you need to do here, and you have the index path
}

答案 1 :(得分:0)

// Ignore undeclared selector warnings as this method is implemented in the VC
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
[moreButton addTarget:nil action: @selector(userPressedShareBasementButton:) forControlEvents: UIControlEventTouchUpInside];
#pragma clang diagnostic pop

我发现设置addTarget:nil只是将方法调用传递给链,因此仅在View控制器上实现此方法意味着它会按预期调用。