UITableViewCell 子类导致无法识别的选择器发送问题
UITableViewCell subclass causing unrecognized selector sent issue
我正在对 UITableViewCell 进行子类化,这导致我的应用程序崩溃...我遇到的问题是我的单元格一直在自我绘制,所以我在搜索后找到的答案是一个子类,但我有一些问题。这是我的代码。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *requestCell = @"requestCell";
RequestCell *cell;
switch (indexPath.section) {
{case 0:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
if (cell == nil) {
cell = [[RequestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:requestCell];
}
//APP CRASHES ON THIS LINE
cell.requestTitle.frame = CGRectMake(60, 5, self.view.frame.size.width - 70, 30);
cell.detailTitle.frame = CGRectMake(60, 30, self.view.frame.size.width - 70, 25);
Request *request = [[Request alloc] init];
request = self.isNotFilledList[indexPath.row];
cell.requestTitle.text = request.productName;
cell.detailTitle.text = request.dateRequested;
cell.detailTitle.font = [UIFont systemFontOfSize:11.0];
NSString *imageURL = @"myurl";
imageURL = [imageURL stringByAppendingString:request.productImageName];
cell.requestImageButton.frame = CGRectMake(5, 5, 50, 50);
[cell.requestImageButton sd_setBackgroundImageWithURL:[NSURL URLWithString:imageURL] forState:UIControlStateNormal];
NSLog(@"request name %@", request.productName);
return cell;
break;}
{case 1:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
if (cell == nil) {
cell = [[RequestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:requestCell];
}
Request *request = [[Request alloc] init];
request = [self.isFilledList objectAtIndex:indexPath.row];
cell.textLabel.text = request.productName;
return cell;
break;}
default:
break;
}
return cell;
}
还有我的 RequestCell 类
@interface RequestCell : UITableViewCell
@property (strong, nonatomic) UILabel *requestTitle;
@property (strong, nonatomic) UILabel *detailTitle;
@property (strong, nonatomic) UIButton *requestImageButton;
和 .m 文件
#import "RequestCell.h"
@implementation RequestCell
- (void)awakeFromNib {
// Initialization code
}
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
-(UILabel *)requestTitle
{
if(!_requestTitle)
{
_requestTitle = [[UILabel alloc] init];
}
return _requestTitle;
}
-(UILabel *)detailTitle
{
if(!_detailTitle)
{
_detailTitle = [[UILabel alloc] init];
}
return _detailTitle;
}
-(UIButton *)requestImageButton
{
if(!_requestImageButton)
{
_requestImageButton = [[UIButton alloc] init];
}
return _requestImageButton;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
我做错了什么???
原始代码 **在顶部重新绘制单元格
switch (indexPath.section) {
{case 0:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:requestCell];
}
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(55, 5, self.view.frame.size.width - 60, 30)];
UILabel *detailTitle = [[UILabel alloc] initWithFrame:CGRectMake(55, 30, self.view.frame.size.width - 60, 25)];
Request *request = [[Request alloc] init];
request = self.isNotFilledList[indexPath.row];
title.text = request.productName;
detailTitle.text = request.dateRequested;
NSString *imageURL = @"myurl";
imageURL = [imageURL stringByAppendingString:request.productImageName];
UIButton *keyImageButton = [[UIButton alloc] initWithFrame:CGRectMake(5, 5, 50, 50)];
//[[keyImageButton imageView] setContentMode: UIViewContentModeScaleAspectFill];
[keyImageButton sd_setBackgroundImageWithURL:[NSURL URLWithString:imageURL] forState:UIControlStateNormal];
[cell addSubview:detailTitle];
[cell addSubview:title];
[cell addSubview:keyImageButton];
NSLog(@"request name %@", request.productName);
return cell;
break;}
您不需要手动实例化 Cell 实例变量。尝试删除额外的功能
-(UILabel *)requestTitle
{
if(!_requestTitle)
{
_requestTitle = [[UILabel alloc] init];
}
return _requestTitle;
}
-(UILabel *)detailTitle
{
if(!_detailTitle)
{
_detailTitle = [[UILabel alloc] init];
}
return _detailTitle;
}
-(UIButton *)requestImageButton
{
if(!_requestImageButton)
{
_requestImageButton = [[UIButton alloc] init];
}
return _requestImageButton;
}
赞成这个
@implementation RequestCell
@synethesize requestTitle;
@synthesize detailTitle;
@synthesize requestImageButton;
编辑:
啊,我想我现在明白问题所在了。您使用的 dequeueReusableCellWithIdentifier:forIndexPath:
是新的 iOS 6 并且设计为从不 return 零单元格(以防止应用程序崩溃和开发人员方便)。因此,您后面的 if 语句适用于 OLD dequeue 方法,它只是 dequeueReusableCellWithIdentifier
修复应该改变这个:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
对此:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell];
more details can be found here
如果您的单元格是在情节提要中制作的,那么 initWithCoder:
是调用的 init 方法,而不是 initWithStyle:reuseIdentifier:
。所以,重写它,创建你的标签,然后将它们添加到那里的 contentView 中。此外,没有理由在您的 cellForRowAtIndexPath
方法中使用 if cell == nil 子句,因为您的 dequeue 方法保证 return 一个单元格。
你应该改变的另一件事是,
Request *request = [[Request alloc] init];
request = self.isNotFilledList[indexPath.row];
您在第一行中实例化了一个 Request 对象,但随后在下一行中将其重新定义为 self.isNotFilledList[indexPath.row] 并将其丢弃。你应该有,
Request *request = self.isNotFilledList[indexPath.row];
我正在对 UITableViewCell 进行子类化,这导致我的应用程序崩溃...我遇到的问题是我的单元格一直在自我绘制,所以我在搜索后找到的答案是一个子类,但我有一些问题。这是我的代码。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *requestCell = @"requestCell";
RequestCell *cell;
switch (indexPath.section) {
{case 0:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
if (cell == nil) {
cell = [[RequestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:requestCell];
}
//APP CRASHES ON THIS LINE
cell.requestTitle.frame = CGRectMake(60, 5, self.view.frame.size.width - 70, 30);
cell.detailTitle.frame = CGRectMake(60, 30, self.view.frame.size.width - 70, 25);
Request *request = [[Request alloc] init];
request = self.isNotFilledList[indexPath.row];
cell.requestTitle.text = request.productName;
cell.detailTitle.text = request.dateRequested;
cell.detailTitle.font = [UIFont systemFontOfSize:11.0];
NSString *imageURL = @"myurl";
imageURL = [imageURL stringByAppendingString:request.productImageName];
cell.requestImageButton.frame = CGRectMake(5, 5, 50, 50);
[cell.requestImageButton sd_setBackgroundImageWithURL:[NSURL URLWithString:imageURL] forState:UIControlStateNormal];
NSLog(@"request name %@", request.productName);
return cell;
break;}
{case 1:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
if (cell == nil) {
cell = [[RequestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:requestCell];
}
Request *request = [[Request alloc] init];
request = [self.isFilledList objectAtIndex:indexPath.row];
cell.textLabel.text = request.productName;
return cell;
break;}
default:
break;
}
return cell;
}
还有我的 RequestCell 类
@interface RequestCell : UITableViewCell
@property (strong, nonatomic) UILabel *requestTitle;
@property (strong, nonatomic) UILabel *detailTitle;
@property (strong, nonatomic) UIButton *requestImageButton;
和 .m 文件
#import "RequestCell.h"
@implementation RequestCell
- (void)awakeFromNib {
// Initialization code
}
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
-(UILabel *)requestTitle
{
if(!_requestTitle)
{
_requestTitle = [[UILabel alloc] init];
}
return _requestTitle;
}
-(UILabel *)detailTitle
{
if(!_detailTitle)
{
_detailTitle = [[UILabel alloc] init];
}
return _detailTitle;
}
-(UIButton *)requestImageButton
{
if(!_requestImageButton)
{
_requestImageButton = [[UIButton alloc] init];
}
return _requestImageButton;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
我做错了什么???
原始代码 **在顶部重新绘制单元格
switch (indexPath.section) {
{case 0:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:requestCell];
}
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(55, 5, self.view.frame.size.width - 60, 30)];
UILabel *detailTitle = [[UILabel alloc] initWithFrame:CGRectMake(55, 30, self.view.frame.size.width - 60, 25)];
Request *request = [[Request alloc] init];
request = self.isNotFilledList[indexPath.row];
title.text = request.productName;
detailTitle.text = request.dateRequested;
NSString *imageURL = @"myurl";
imageURL = [imageURL stringByAppendingString:request.productImageName];
UIButton *keyImageButton = [[UIButton alloc] initWithFrame:CGRectMake(5, 5, 50, 50)];
//[[keyImageButton imageView] setContentMode: UIViewContentModeScaleAspectFill];
[keyImageButton sd_setBackgroundImageWithURL:[NSURL URLWithString:imageURL] forState:UIControlStateNormal];
[cell addSubview:detailTitle];
[cell addSubview:title];
[cell addSubview:keyImageButton];
NSLog(@"request name %@", request.productName);
return cell;
break;}
您不需要手动实例化 Cell 实例变量。尝试删除额外的功能
-(UILabel *)requestTitle
{
if(!_requestTitle)
{
_requestTitle = [[UILabel alloc] init];
}
return _requestTitle;
}
-(UILabel *)detailTitle
{
if(!_detailTitle)
{
_detailTitle = [[UILabel alloc] init];
}
return _detailTitle;
}
-(UIButton *)requestImageButton
{
if(!_requestImageButton)
{
_requestImageButton = [[UIButton alloc] init];
}
return _requestImageButton;
}
赞成这个
@implementation RequestCell
@synethesize requestTitle;
@synthesize detailTitle;
@synthesize requestImageButton;
编辑:
啊,我想我现在明白问题所在了。您使用的 dequeueReusableCellWithIdentifier:forIndexPath:
是新的 iOS 6 并且设计为从不 return 零单元格(以防止应用程序崩溃和开发人员方便)。因此,您后面的 if 语句适用于 OLD dequeue 方法,它只是 dequeueReusableCellWithIdentifier
修复应该改变这个:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell forIndexPath:indexPath];
对此:
cell = [tableView dequeueReusableCellWithIdentifier:requestCell];
more details can be found here
如果您的单元格是在情节提要中制作的,那么 initWithCoder:
是调用的 init 方法,而不是 initWithStyle:reuseIdentifier:
。所以,重写它,创建你的标签,然后将它们添加到那里的 contentView 中。此外,没有理由在您的 cellForRowAtIndexPath
方法中使用 if cell == nil 子句,因为您的 dequeue 方法保证 return 一个单元格。
你应该改变的另一件事是,
Request *request = [[Request alloc] init];
request = self.isNotFilledList[indexPath.row];
您在第一行中实例化了一个 Request 对象,但随后在下一行中将其重新定义为 self.isNotFilledList[indexPath.row] 并将其丢弃。你应该有,
Request *request = self.isNotFilledList[indexPath.row];