从Nib加载可重用的UITableViewCell
我可以使用http://forums.macrumors.com/showthread.php?t=545061中的线程描述的技术来devise自定义的UITableViewCells并加载它们。 但是,使用该方法不再允许您使用reuseIdentifier来初始化单元,这意味着您必须在每次调用时创build每个单元的全新实例。 有没有人想出一个好的方法来caching特定的单元格types的重用,但仍然能够在界面生成器中devise它们?
只需使用适当的方法签名来实现一个方法:
- (NSString *) reuseIdentifier { return @"myIdentifier"; }
实际上,由于您是在Interface Builder中构build单元,所以只需在其中设置重用标识:
或者如果您正在运行Xcode 4,请检查“属性”检查器选项卡:
(编辑:你的XIB由XCode生成后,它包含一个空的UIView,但是我们需要一个UITableViewCell;所以你必须手动删除UIView并插入一个Table View Cell,当然,IB不会显示任何UITableViewCell参数UIView的。)
现在,在iOS 5中有一个适当的UITableView方法:
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
我不记得最初是在哪里find这个代码的,但是到目前为止我一直在为我工作。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"CustomTableCell"; static NSString *CellNib = @"CustomTableCellView"; UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil]; cell = (UITableViewCell *)[nib objectAtIndex:0]; } // perform additional custom work... return cell; }
示例Interface Builder安装程序…
替代文字160wpb4.jpg
看看我给这个问题的答案:
是否有可能在Interface Builder中deviseNSCell子类?
不仅可以在IB中devise一个UITableViewCell,而且还是可取的,因为否则所有的手动连线和多个元素的放置都非常繁琐。 只要您尽可能使所有元素不透明,就可以保持性能。 对于UITableViewCell的属性,在IB中设置reuseID,然后在试图出队时使用代码中的匹配重用ID。
我还从去年WWDC的一些主持人那里听说,你不应该在IB做表格视图单元格,但是它是一个双层的负载。
截至iOS大约4.0版本,iOS文档中有特定的说明使得这项工作超快:
向下滚动到讨论UITableViewCell子类的地方。
这是另一个select:
NSString * cellId = @"reuseCell"; //... NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil]; for (id obj in nibObjects) { if ([obj isKindOfClass:[CustomTableCell class]]) { cell = obj; [cell setValue:cellId forKey:@"reuseIdentifier"]; break; } }
我以类似的方式创build自定义视图单元格 – 除了通过IBOutlet连接单元格外。
[nib objectAt...]
方法容易改变数组中的项目的位置。
UIViewController
方法是很好的 – 只是试了一下,它工作得很好。
但…
在所有情况下, initWithStyle
构造函数都不会被调用,所以没有默认的初始化。
我已经阅读了有关使用initWithCoder
或awakeFromNib
各种地方,但没有确凿的证据表明这些方法是正确的。
除了显式调用cellForRowAtIndexPath
方法的一些初始化方法,我还没有find答案。
前一阵子,我在blog.atebits.com上发现了一个很棒的博客文章,并开始使用Loren Brichter ABTableViewCell类来完成我所有的UITableViewCells。
你最终得到一个简单的容器UIView把所有的小部件,滚动是闪电般的。
希望这是有用的。
这种技术也可以工作,并且不需要在视图控制器中使用时髦的ivar来进行内存pipe理。 这里,自定义表格视图单元格位于名为“CustomCell.xib”的xib中。
static NSData *sLoadedCustomCell = nil; cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"]; if (cell == nil) { if (sLoadedCustomCell == nil) { // Load the custom table cell xib // and extract a reference to the cell object returned // and cache it in a static to avoid reloading the nib again. for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil]) { if ([loadedObject isKindOfClass:[UITableViewCell class]]) { sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain]; break; } } cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell]; }
路易斯方法为我工作。 这是我用来从笔尖创buildUITableViewCell的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"]; if (cell == nil) { UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil]; cell = (PostCell *)c.view; [c release]; } return cell; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = @"CustomCell"; CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil]; cell = [nib objectAtIndex:0]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } return cell; }
gustavogb解决scheme不适合我,我试过的是:
ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil]; [[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil]; cell = [c.blogTableViewCell retain]; [c release];
这似乎工作。 blogTableViewCell是单元的IBOutlet,ChainesController是文件的所有者。
从关于dequeueWithReuseIdentifier
的UITableView文档:“标识要重用的单元格对象的string。默认情况下,可重用单元格的标识符是其类名称,但可以将其更改为任意值。
重申 – 重新使用certificate自己是有风险的。 如果您有您的单元格子类的两个子类,并在一个表视图中使用这两个子类会发生什么? 如果他们发送重用标识符调用超级你会出队一个错误types的单元格…………..我认为你需要重写reuseIdentifier方法,但它有返回一个代替的标识符串。 或者,如果没有指定,请将它作为string返回。
在iPhone技术讲座中,我向一位iPhone工程师询问了这件事。 他的回答是:“是的,可以用IB来创build单元格,但是不要,请不要。
我跟随了本Mosher联系的苹果公司的指示(谢谢!),但发现苹果省略了重要的一点。 他们在IB中devise的对象只是一个UITableViewCell,就像从它加载的variables一样。 但是,如果您实际上将其设置为UITableViewCell的自定义子类,并为该子类编写代码文件,则可以在代码中编写IBOutlet声明和IBAction方法,并将它们连接到IB中的自定义元素。 那么不需要使用视图标签来访问这些元素,你可以创build任何你想要的疯狂的单元格。 这是cocoa触摸天堂。