【问题标题】:Multple buttons in CustomCell. Which button in which row is clicked?自定义单元格中的多个按钮。单击了哪一行中的哪个按钮?
【发布时间】:2012-02-03 18:07:48
【问题描述】:

我正在做一个学生项目,我需要知道点击了哪一行中的哪个按钮。

每一行都有不同的标签,一个喜欢按钮和一个不喜欢按钮。

我确实知道如何使用 NSIndexPath.row 来检测按下了哪一行,但在这种情况下,我需要知道哪一行以及该行中的哪个按钮被按下。

我已经在整个 SO 中搜索了一个很好的解决方案来检测在每行有多个按钮时单击了哪一行按钮。

根据我阅读其他帖子的理解,使用 button.tag 可能非常难以预测,因此我宁愿尽可能使用不同的方法。

我已经看到很多应用程序都实现了这一点,因此必须有一种最佳方式来实现这一点。大家有什么好的建议吗?

代码:

SearchCell.h

@interface SearchCell : UITableViewCell {

IBOutlet UIButton *likebutton2;
IBOutlet UIButton *dislikebutton2;

}

@property (nonatomic,retain) IBOutlet UILabel *track_label;
@property (nonatomic,retain) IBOutlet UILabel *artist_label;
@property (nonatomic,retain) IBOutlet UILabel *album_label;

@property (nonatomic,retain) IBOutlet UIButton *likebutton2;
@property (nonatomic,retain) IBOutlet UIButton *dislikebutton2;

@property (nonatomic, copy) void (^onButton)(UIButton *button);

- (void)buttonAction:(UIButton *)sender;

@end

SearchCell.m

#import "SearchCell.h"
#import "RootViewController.h"

@implementation SearchCell

@synthesize likebutton2, dislikebutton2, track_label, artist_label, album_label;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
    // Initialization code.

}
    return self;
}

- (void)buttonAction:(UIButton *)sender
{
    self.onButton(sender);
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

    [super setSelected:selected animated:animated];

// Configure the view for the selected state.
}

- (void)dealloc {
    [super dealloc];
}

@end

cellForRowAtIndexPath

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

NSString *uniqueIdentifier = @"searchCell";

SearchCell *cell = nil;

Search *currentSearch = nil;

cell = (SearchCell *) [self.tableView dequeueReusableCellWithIdentifier:uniqueIdentifier];

if (tableView == [[self searchDisplayController] searchResultsTableView]) //Just from some previous debugging
{
    currentSearch = [[searchxmlParser searchhits] objectAtIndex:indexPath.row];
}

if(!cell)
{
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"SearchCell" owner:nil options:nil];

    for (id currentObject in topLevelObjects) {
        if ([currentObject isKindOfClass:[SearchCell class]]) {
            cell = (SearchCell *)currentObject;

            [cell.likebutton2 addTarget:cell action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
            [cell.dislikebutton2 addTarget:cell action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
            cell.likebutton2.tag = 1;
            cell.dislikebutton2.tag = 2;    

            break;
        }
    }

}

cell.onButton = ^(UIButton *theButton) {
    [self handleButton:theButton indexPath:indexPath];
}

cell.track_label.text = [currentSearch track];
cell.artist_label.text = [currentSearch artist];

return cell;    
}

感谢您的帮助:)!

【问题讨论】:

    标签: iphone uitableview nsindexpath custom-cell


    【解决方案1】:

    为什么不这样做:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSString *reuseIdentifier = @"MyCell";
        MyCustomCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    
        if (cell == nil) {
    
            cell = [[[MyCustomCell alloc] init] autorelease];
    
            [cell.firstButton addTarget:self action:@selector(firstButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
            [cell.secondButton addTarget:self action:@selector(secondButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
        }
    
        [cell.firstButton setTag:indexPath.row];
        [cell.secondButton setTag:indexPath.row];
    
        // other cell setup...
    
        return cell;
    }
    
    - (void)firstButtonPressed:(id)sender {
    
        NSInteger cellRow = [sender tag];
    
        // do things...
    }
    
    - (void)secondButtonPressed:(id)sender {
    
        NSInteger cellRow = [sender tag];
    
        // do things...
    }
    

    这假设您的UITableView 中只有一个部分,使用多个部分执行此操作有点复杂。

    【讨论】:

    • 这样做的一个缺点是你无法分辨出哪个按钮被按下了;以这种方式使用标签会更加复杂。
    • @CarlVeazey 每个不同的按钮都有不同的操作方法。 firstButtonPressed: 是第一个按钮,secondButtonPressed: 是第二个按钮,依此类推。
    • @EllNeal 我一定会试试这个 :) 我会尽快回复你!
    • @EllNeal heh,duh,这就是我浏览您的解决方案得到的:)
    【解决方案2】:

    我认为使用块将是一个很好的方法,仍然使用@EllNeal 解决方案中的标签:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSString *reuseIdentifier = @"MyCell";
    MyCustomCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    
    if (cell == nil) {
    
        cell = [[[MyCustomCell alloc] init] autorelease];
    
        [cell.button1 addTarget:cell action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [cell.button2 addTarget:cell action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        cell.button1.tag = 1;
        cell.button2.tag = 2;
    }
    
    cell.onButton = ^(UIButton *theButton) {
         [self handleButton:theButton indexPath:indexPath];
    }
    
    return cell;
    

    那么你告诉哪个按钮被按下的处理程序将是这样的:

    - (void)handleButton:(UIButton *)button indexPath:(NSIndexPath *)indexPath
    {
       //Use tag of button to identify which button was tapped, as well as the indexPath
    }
    

    您的单元格代码看起来有点像这样:

    @interface MyCustomCell
    ...
    - (void)buttonAction:(UIButton *)sender
    @property (nonatomic, copy) void (^onButton)(UIButton *button);
    ...
    @end
    
    @implementation
    ...
    - (void)buttonAction:(UIButton *)sender
    {
        self.onButton(sender);
    }
    ...
    @end
    

    希望这会有所帮助!

    【讨论】:

    • 我收到了对成员“likebutton”的请求,而不是结构或联合。
    • 好吧,@CarlVeazey 。我决定实现您的两者的代码,因为我是新手,您的答案解释清楚且易于理解。就是这么说的。我收到了我在上面评论中提到的 4 行的错误:`if (cell == nil) {' 有什么建议:)?如果你帮我完成这项工作,我将永远感激不尽!
    • @AlexanderNorway,您是否将likebutton 定义为单元格上的属性?
    • 是的,@CarlVeazey。在自定义单元格中。我那里有两个按钮。不喜欢按钮和喜欢按钮。我可以在几分钟内发布代码。
    • 听起来不错。很高兴看到您的 cellForRow... 方法和您的自定义单元格的@interface
    【解决方案3】:

    使用.tag 属性,它非常可靠且可预测。

    如果您不这么认为,请显示一些代码。

    【讨论】:

    • Okey @mvds ,在另一篇文章中提到它不可靠,你看。我的错。你有什么好的使用例子吗?
    • 几十个,只需将 .tag 属性设置为标识按钮的某个值。然后,如果代码不起作用,请在此处发布。
    • 您可以利用属性是 32 位宽的事实,因此您可以在其中放置多个数字; button.tag = (indexPath.section<<16) | indexPath.row。执行相反的操作以从按钮快速获取部分和行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 2017-12-17
    相关资源
    最近更新 更多