尝试实现CustomCell的“简单”, 我有一个普通的tableViewController,使用普通的“默认”方法渲染得很好, 但是我需要用一些UILabel和一个UIImage实现一个Custom单元格。
所以我创建了CustomCell.h,CustomCell.m,CustomCell.xib
.H
@interface CustomCell : UITableViewCell <UITextViewDelegate>
{
IBOutlet UIImageView *image;
IBOutlet UILabel *name;
IBOutlet UILabel *date;
IBOutlet UILabel *comment;
}
@property (retain,nonatomic) IBOutlet UIImageView *image;
@property (retain,nonatomic) IBOutlet UILabel *name;
@property (retain,nonatomic) IBOutlet UILabel *date;
@property (retain,nonatomic) IBOutlet UILabel *comment;
和.M
@implementation CustomCell
@synthesize image;
@synthesize name;
@synthesize date;
@synthesize comment;
#pragma mark -
#pragma mark View lifecycle
- (id) initWithController: (Controller *) ctnlr
{
ControllerPointer = ctnlr;
return(self);
}
- (void) SetImage:(UIImageView*)Image
{
image = Image;
}
- (void) SetName:(NSString*)Name
{
[Name retain];
[name.text release];
name.text = Name;
}
- (void) SetDate:(NSString*)Date
{
[Date retain];
[date.text release];
date.text = Date;
}
- (void) SetComment:(NSString*)Comment
{
[Comment retain];
[comment.text release];
comment.text = Comment;
}
无论如何,当我尝试在cellForRowAtIndexPath中创建这些自定义单元时(正如人们所期望的那样)我只剩下一个空白屏幕。所以很明显我错过了一些很大的东西...当我使用“Interface Builder”创建.XIB文件时,我确保将“引用插座”连接到相应的标签和图像。
因此遵循Xcode框架似乎工作方式的隐含逻辑, 我遵循相同的推理(缺乏一个确切的例子)没有工作...... 无论如何,如果有任何想要启发我的IPhone极客... (是的,没有“[某事发布]”电话,我甚至不确定是否需要分配任何东西。请告诉我只有几个电话我要离开,它不能超过像这样简单的东西吧......?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] lastObject];
}
NSUInteger row = [indexPath row];
SnsObject *sObj = [SnsArray objectAtIndex:row];
[cell SetName:[sObj getUserName]];
NSUInteger row = [indexPath row];
SnsObject *sObj = [SnsArray objectAtIndex:row];
cell.name = [[UILabel alloc]init];
cell.name.text = [sObj getUserName];
cell.date = [[UILabel alloc]init];
cell.date.text = [sObj getDateTime];
cell.comment = [[UILabel alloc]init];
cell.comment.text = [sObj getCommentText];
cell.image = [[UIImageView alloc]init];
cell.image.image = [sObj getImageUrl];
return(cell)
}
提前致谢!
答案 0 :(得分:4)
除了mrcrowl提到的关于现在需要“alloc-init”出口的代码之外,还有其他问题。特别是,这一行:
cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] lastObject];
这不是用于从.xib加载自定义tableview单元格的典型习惯用法。首先,您传递“owner:self”,这意味着您希望将.xib文件中的outlet对象与 tableviewcontroller 对象中的outlet成员挂钩,可能不是您想要的。 其次,你依赖于从loadNibNamed:owner:options:返回的对象的顺序,虽然它可能在今天工作,但明天可能无法工作,或者在新的iOS版本上运行。
相反,通常的习惯用法是在tableviewcontroller中为整个tableviewcell声明一个插座: (在.h文件中):
...
UITableViewCell *tvCell;
...
@property (nonatomic, retain) IBOutlet UITableViewCell *tvCell;
然后代替你的行,你有这个:
[[NSBundle mainBundle] loadNibNamed:@"NewsArchiveTitleTvCell" owner:self options:nil];
cell = tvCell;
self.tvCell = nil;
通常情况下,这不是通过子类化完成的,请注意我没有将类声明为CustomCell,而是将其作为vanilla UITableViewCell声明。那么你如何得到那些讨厌的子视图,以便你可以配置它们?使用标签是正常的方式:
...
#define kMyKewlLabelTag 1
...
UILabel *kewlLabel = (UILabel *) [cell viewWithTag:kMyKewlLabelTag];
kewlLabel.text = [NSString stringWithFormat:@"Hi there from row %d!", indexPath.row];
...
编辑: 编辑:这里有更多细节,评论太短,无法解决“这里发生了什么?”题。这是我的一个应用程序的摘录,它从.xib加载UITableViewCell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"MyShoppingCartTvCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:@"ShoppingCartTvCell" owner:self options:nil];
cell = tvCell;
self.tvCell = nil;
}
...
// (insert code to grab model data for this row)
...
UILabel *nameLabel = (UILabel *) [cell viewWithTag:1];
nameLabel.text = itemNameStr;
UILabel *countLabel = (UILabel *) [cell viewWithTag:2];
countLabel.text = [NSString stringWithFormat:@"%d", itemCount];
UIImageView *iv = (UIImageView *) [cell viewWithTag:3];
...
以下是这里发生的事情:
没有自定义的UITableViewCell子类,只有一个名为“ShoppingCartTvCell.xib”的.xib文件包含一个UITableViewCell,而UI元素放在UITableViewCell中。必须为每行更改数据的UI元素分配一个唯一标记(标记字段位于IB中的CMD-1属性检查器中),以便您的代码可以获取这些对象的句柄以更改它们(自定义标签,图像等) 。确保不使用“0”,因为默认情况下所有元素都有0标记。另外,请确保CMD-1 Attributes Inspector中UITableViewCell的Identifier字段是CellIdentifier字符串。
.xib文件的文件所有者是您要在其中显示单元格的表视图控制器。更确切地说,它可以是包含IBOutlet UITableViewCell * tvCell的任何类;会员。它是此类的一个实例,您作为所有者传递给loadNibNamed:owner:options:。只要链接插座的值在所有者中为零,当您调用loadNibNamed:owner:options时,所有者的出口将使用.xib中的对象填充(只要连接在.xib中进行)。 IB中的xib)。理解这是Apple编程中的一个神奇时刻,为您打开全新的视野:)。
您必须设置self.tvCell = nil;
以准备需要从.xib加载的下一个cellForRowAtIndexPath。我有时在loadNibNamed:owner:options:之前设置为nil,我觉得实际上有点安全。
以下是从.xib加载UITableViewCells的方法:
在xcode中,添加一个IBOutlet UITableViewCell * tvCell;到你的UITableViewController类(如果你愿意,包括属性声明)
在xcode项目中,创建一个新文件,用户界面,空Xib。在IB
在IB中,将TableViewCell从库中拖到First Responder下的空.xib文件中
单击文件的所有者,CMD-4(识别检查器),然后在Class下选择包含您添加的IBOutlet UITableViewCell * tvCell的类(可能是您的UITableViewController子类,您操作表的类)。
按住Ctrl键从文件所有者拖动到UITableViewCell,然后选择要连接的插座。当您使用File的所有者实例作为“所有者”参数调用loadNibNamed:owner:options时,这个字段将保存new-loaded-from-xib UITableViewCell。
将UI元素添加到UITableViewCell中(确保它们在 UITableViewCell层次结构中)。您要为每行自定义的任何元素都需要唯一的标记值。
按照上面我在cellForRowAtIndexPath中提供的配方
有一个神奇的时刻,你开始了解.xib文件和文件的所有者对象如何真正协同工作,并开始在IB中创建很多很酷的UITableViewCells和其他自定义视图对象,因为它比创建更容易和更好他们在代码(IMNSHO)。
答案 1 :(得分:2)
从.xib加载UITableViewCell时,您不需要手动创建控件。
例如,这种事情是不必要的:
cell.name = [[UILabel alloc]init];
这将使用具有零帧的新标签替换从xib加载的标签 - 也就是说,新标签将位于0,0并且没有宽度或高度。因此,没有工作。
假设您已将xib正确连接到CustomCell的IBOutlets,它们控制您正在寻找的应该已经存在。
P.S。如果我在你的方法名称中读得太多,请原谅我,但我认为这一行也不会起作用,因为.image属性需要一个UIImage:
cell.image.image = [sObj getImageUrl];
答案 2 :(得分:-1)
好的...感谢所有人提供了良好的意见,但有时候最简单的答案不仅是最有说服力的,而且是最好的...这就是我发现的工作方式,尽可能保持简单,不改变一个功能之外的东西。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CustomCellIdentifier";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
for(id oneObject in nib)
{
if([oneObject isKindOfClass:[CustomCell class]])
{
cell = (CustomCell*)oneObject;
}
}
}
NSUInteger row = [indexPath row];
printf("MainMessageBoard.m cellForRowAtIndexPath = [%i]\n",row);
SnsObject *sObj = [SnsArray objectAtIndex:row];
cell.Name.text = [sObj getUserName];
cell.Date.text = [sObj getDateTime];
cell.Comment.text = [sObj getCommentText];
cell.Image.image = [self resizeImage: [self imageFromURLString: [sObj getImageUrl]] scaledToSize:CGSizeMake(32.0f, 32.0f)];
cell.CommentCount.text = [NSString stringWithFormat:@"(%d)", [sObj getCommentCount]];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return(cell);
}