Ios 复制UITableViewCell
我正在从nib文件读取Ios 复制UITableViewCell,ios,objective-c,iphone,uitableview,cocoa-touch,Ios,Objective C,Iphone,Uitableview,Cocoa Touch,我正在从nib文件读取tableView:cellforrowatinexpath:中的自定义表格单元格。这对我来说效果很好,只是速度很慢 现在,我知道从长远来看,正确的做法是完全用代码创建单元格,并使用单个视图,等等。但这是一个原型,我不想投入那么多精力 现在,如果我在UIViewController子类中只读取一次nib,然后tableView:cellforrowatinexpath:复制它,我会很高兴。我在这里的假设是,复制要比读取nib快 下面是我用来加载nib的内容,我从viewDi
tableView:cellforrowatinexpath:
中的自定义表格单元格。这对我来说效果很好,只是速度很慢
现在,我知道从长远来看,正确的做法是完全用代码创建单元格,并使用单个视图,等等。但这是一个原型,我不想投入那么多精力
现在,如果我在UIViewController
子类中只读取一次nib,然后tableView:cellforrowatinexpath:
复制它,我会很高兴。我在这里的假设是,复制要比读取nib快
下面是我用来加载nib的内容,我从viewDidLoad:
(和retain
after)调用它
到目前为止一切都很好。但问题是:我如何一遍又一遍地复制这个?有可能吗
我尝试了[\u cachedObject copy]
和[\u cachedObject mutableCopy]
但是UITableViewCell
不支持这两种复制协议
如果必须的话,我可以告诉他们忽略速度,直到我准备完全移除笔尖,但是如果这里有一个低垂的果实,我宁愿让它运行得快一点
有什么想法吗?使用表视图中内置的细胞克隆。苹果知道生成大量表单元格的速度很慢。查看此方法的文档:
- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier
创建一次单元,然后在请求新单元时,使用该方法克隆现有单元。然后,您只需更改新单元格需要更改的内容,并返回单元格对象
另外,请查看Apple提供的使用此方法的table view realted示例代码,并向您展示正确的方法。你的手机是从笔尖加载的,这一点都不重要
次要澄清:我认为上述方法不适合你克隆细胞。取而代之的是,它将屏幕上滚动的单元格对象移到一个新的位置。所以它实际上是重复使用一个细胞。因此,请确保您的自定义表视图可以设置为初始化之外所需的所有新值。嗯,我不确定为什么所有教程都没有指定此步骤 从Nib使用自己的自定义UITableViewCell时,仅调用dequeueReusableCellWithIdentifier是不够的。您必须在IB中指定“标识符”,仅在表视图单元格选项卡部分指定
然后确保您在IB中输入的标识符与您用于dequeueReusableCellWithIdentifier的标识符相同。对此解决方案并不自豪,但它可以与尽可能多的IB绑定一起工作: 接口(AlbumTableViewCell是UITableViewCell的子类,其实例在AlbumViewController的XIB文件中定义): 实施(取消归档/归档复制/克隆表视图单元格):
我认为表单元的处理可以和出列机制一起使用,这将允许一次性创建单元(从nib或以编程方式创建,或从其他nib自动加载并链接为IB中的出口),然后在需要时克隆它或将其出列 UITableViewCell不符合NSCopying协议,但它支持键控存档/取消存档机制,因此可以用于克隆 “基于答案” “我的数据源委托方法如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellID = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];
if (!cell) {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
// ... config ...
return cell;
}
在我的例子中,self.tableViewCell是一个从view的nib文件加载一次的单元格
我没有测试什么会更快:“archive+unarchive”来克隆,或者“load nib file+unarchive”在-loadNibNamed:owner:options:的情况下框架会做什么,我使用这种方法只是出于方便的考虑,但是内存操作和文件操作很可能会更快
编辑:看起来不像一开始看起来那么容易。由于UIImage不符合NSCoding,如果没有其他代码,则无法复制配置了UIImageView的单元格。是的,复制整个图像绝对不是一个好的做法,为苹果公司指出这一点干杯。这里是Swift
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell?
let cellId = String(format: "Cell%d", indexPath.row)
cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?
if cell == nil {
let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
}
// do some stuff
return cell!
}
非常感谢。我忘记了
dequeueReusableCellWithIdentifier
。现在我正在使用它,但它仍然比我想要的慢。这表明瓶颈在于绘图,这将不得不等到我有时间应用其他快速表格技巧。但现在我知道怎么回事了!因为重用对象要比克隆对象快得多,所以您的方法会更慢。很高兴我能帮忙。这实际上不是这个问题的正确答案。初始设置时,对于每个可见单元,排队将返回nil。因此,在该if(cell==nil)
块中,您将希望创建一个新的UITableViewCell,可能是通过从nib加载。我还希望从控制器中的IBOutlet复制UITableViewCell,该控制器已连接到nib中设计的UITableViewCell。但是复制失败,说它不支持copyWithZone。有没有办法在Interface Builder中创建UITableViewCell
的原型实例,并根据UITableView
的需要克隆该实例?这比按代码设置单元格容易得多。谢谢。@adib有一个名为UINib
的类是SDK 4.0。但在目前可用的操作系统中,这不是一件容易的事。哇,如果不是为了这篇文章,我永远不会知道如何复制UITableViewCell。Thx很多。通过归档/取消归档,约束无法实现:-(
@implementation AlbumsViewController
@synthesize tableViewCellTrack;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
AlbumTableViewCell *cell = (AlbumTableViewCell *)[tableView dequeueReusableCellWithIdentifier: @"AlbumCell"];
if (cell == nil) {
AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease];
[[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil];
cell = albumsViewController.tableViewCellTrack;
}
cell.labelTitle.text = ...;
cell.labelArtist.text = ...;
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellID = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];
if (!cell) {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
// ... config ...
return cell;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell?
let cellId = String(format: "Cell%d", indexPath.row)
cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?
if cell == nil {
let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
}
// do some stuff
return cell!
}