target:self 的 UIButton 没有发送给自己?

UIButton with target:self not being sent to self?

我正在创建一个新的 UIViewController(称之为 MyViewController),并将视图 (MyView) 添加为 TableViewCell 的子视图。在 MyView 中,有一个按钮。该按钮是在 MyViewController 的初始化期间以编程方式创建的,如下所示:

-(id)initWithFrame:(CGRect)frame {
    self = [super init];
    if(self) {
        [self.view setFrame:frame];

        _yesButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size.width-150, 40, 140, 30)];
        [_yesButton setTitle:@"Yeah!" forState:UIControlStateNormal];
        [_yesButton addTarget:self action:@selector(didClick) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:_yesButton];
    }
    return self;
}

现在,看起来很简单。它显示正确,模拟器中的一切看起来都很棒。

但是,当我在 MyView 中单击“_yesButton”时,出现崩溃并出现以下错误:

-[_UITableViewCellSeparatorView didClick]: unrecognized selector sent to instance 0x7b7f7ec0

什么? “_UITableViewCellSeparatorView”是什么时候出现的?我特意告诉 _yesButton 将 Target 设置为 "self",所以应该将选择器发送到 MyViewController,对吗?我什至可以想象它被绊倒并将其发送到 UITableViewCell,因为 MyView 嵌入在 TableViewCell 中,但为什么是 SeperatorView?

谁能告诉我如何让我的 _yesButton 将调用发送回在其中创建它的 MyViewController?至于加分项,你能解释一下“_UITableViewCellSeparatorView”是如何成为这次对话中的一件事的吗?

编辑: 下面是我在 TableView 中构建单元格并将 MyView 添加到其中的方法。请注意,我故意不对此行使用出列,但如果它是问题的根源,那可能会改变。

UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyViewCell"];

MyViewController *myViewController = [[MyViewController alloc] initWithFrame:cell.contentView.frame];
[cell.contentView addSubview:myViewController.view];

return cell;

而且 didClick 方法目前是空的(它从来没有到达那里,所以我还没有写那么远),但它目前在 MyViewController 中简单地定义为:

-(void)didClick {

}

解决方案#1

其实这是因为你MyViewController没有被ARC保留。正在调用的 dealloc 方法 ID。在您的 UITableViewController 中添加控制器的 ans 实例将解决问题并使 ARC 保留您的控制器。

解决方案#2

尝试这样的事情。

创建自定义 UITableViewCell :

MyCustomCell.h :

#import <UIKit/UIKit.h>

@interface MyCustomCell : UITableViewCell

@property (strong, nonatomic) UIButton *yesButton;

-(id)initWithFrame:(CGRect)frame;

@end

MyCustomCell.m :

#import "MyCustomCell.h"

@implementation MyCustomCell

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

-(id)initWithFrame:(CGRect)frame {
    self = [super init];
    if(self) {
       [self.view setFrame:frame];

       _yesButton = [[UIButton alloc] initWithFrame:CGRectMake(frame)];
       [_yesButton setTitle:@"Yeah!" forState:UIControlStateNormal];
       [self.contentView addSubview:_yesButton];
    }
    return self;
}
@end

在你的UITableViewControllerviewDidLoad函数中:

[self.tableView registerClass:[MyCustomCell class] forCellReuseIdentifier:CellIdentifier];

然后在你的 tableView:cellForRowAtIndexPath:

MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierr forIndexPath:indexPath];
if (cell == nil) {
     cell = [[MyCustomCell alloc] initWithFrame:frame];
     [cell.yesButton addTarget:self action:@selector(didClick) forControlEvents:UIControlEventTouchUpInside];
}

现在在您的 UITableViewController 中实施以下内容:

-(void)didClick {
   // The following identify the in which cell the action has been triggered
   NSSet *touches = [event allTouches];
   UITouch *touch = [touches anyObject];
   CGPoint currentTouchPosition = [touch locationInView:self.tableView];
   NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
   if (indexPath != nil)
   {
    // Do whatever you want for the given cell
   }
}

问题是你认为 MyViewController 的实例,它不是。而是 UITableViewCellSeparatorView.

最大的错误是,您试图通过 class UIViewController 不支持的方法初始化视图控制器,但是而是 UIView:

的一部分
- (id)initWithFrame:(CGRect)frame

我建议您先查看一下再继续。

我认为你采用了错误的方法。

视图单元不像视图那样存在于内存中。可以说,画完了,就不存在了。

对于所有单元格操作,您应该将您的TableViewController 设置为目标,并在该控制器中处理click 方法。 只有此控制器对单元格中的数据和单元格格式具有全局知识。

您可以将按钮的标签设置为行索引,以了解点击了哪一行。

您的 didClick 选择器也不正确。它应该有这种形式

-(void)didClick:(id)sender
{
    NSInteger clickedRow = ((UIButton*)sender).tag
}

所以这样连接:

[_yesButton addTarget:<YourTableController> action:@selector(didClick:) forControlEvents:UIControlEventTouchUpInside];