从官方文档:
重用标识符与表视图的委托创建的UITableViewCell对象相关联,其目的是将其作为表视图的多行的基础(出于性能原因)重用.它在initWithFrame:reuseIdentifier:中分配给单元对象,此后不能更改.UITableView对象维护当前可重用单元的队列(或列表),每个单元都有自己的重用标识符,并使它们可用于dequeueReusableCellWithIdentifier:方法中的委托.
我不明白这一点.嗯,我理解我认为你创建UITableViewCells的基本思想,并尝试尽可能多地重用,而不是创建新的(或类似的东西).但究竟是什么决定一个细胞是否可以重复使用?如果我有两个相同的(视觉)单元格,但有不同的文本(我认为它们不完全相同),它们是否都具有相同的标识符?或者他们应该有不同的?或者在什么情况下你应该使用不同的标识符?
任何人都可以澄清或链接到它的位置吗?
当苹果UITableView
为第一款iPhone 开发时,他们在滚动浏览时会遇到性能问题.然后,一位聪明的工程师发现,造成这种情况的原因是物品的分配需要付出代价,因此他想出了一种重用细胞的方法.
"对象分配具有性能成本,特别是如果分配必须在短时间内重复发生 - 例如,当用户滚动表视图时.如果重用单元而不是分配新单元,则可以大大提高表视图性能."
来源:iOS参考图书馆
要重用您使用的单元格:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Run Code Online (Sandbox Code Playgroud)
现在,我想知道的是,这里究竟发生了什么?如果有一个具有该标识符的单元格并且只返回那个标识符,它是否在TableView中查找?好吧,但是,如果它发送一个引用而不是分配,我有一个表视图,让我们说4个具有相同标识符的单元格都可见.如何在不分配的情况下将自身增加到四个实例中?
我想知道这一点,因为我正在构建一个日历类型组件,并且所有单元格只有更改中的文本具有相同的结构.所以,如果我能以某种方式重用我的细胞而不是分配,我想我可能会获得更好的表现.
我自己的理论是它分配了四个细胞(仅仅因为它也有).当一个单元格从屏幕上消失时,它将被放入TableView重用队列中.当需要一个新的单元时,它会在que中查找具有相同标识符的单元是否可用,它会调用prepareForReuse
该单元上的方法并将其自身从队列中删除.
在我的项目中,我有一个Deprecations警告,initWithFrame:reuseIdentifier:已被弃用
我不知道这是什么意思,有人可以告诉我如何解决这个警告谢谢
这是简短的代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSString *cellValue = [itemsList objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
Run Code Online (Sandbox Code Playgroud)
警告就在那条线上:
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
Run Code Online (Sandbox Code Playgroud) 我最近开始在Xcode 5中构建一个非常基本的待办事项列表作为我的第一个项目.几乎完成了UI设计和构建我现在停留在我的TableView中的数据实现.我在列表中添加了13个项目的列表,并在列表中给出了第一个"ListPrototypeCell"标识符,并且我的所有代码看起来都是正确的.我的项目有3个相同的问题:
Unsupported Configuration; Prototype cells must have reuse identifiers
Run Code Online (Sandbox Code Playgroud)
我已经玩过每个项目的标识符,虽然我被告知我不需要在每个项目上使用标识符,但我仍然会遇到这些错误.
我愿意将我的项目发送给任何认为他们可以帮助我解决问题的人,对于受过训练的人来说,这可能是我犯下的一个非常基本的错误.
我感谢任何帮助!
我有一个子类UICollectionViewCell
.在故事板中可视化地设计单元格,其中包含许多组件,这些组件使用故事板绑定到Swift子类中的变量.
Swift类只提供用于从数据源检索的数据中填充组件的逻辑.
例如:
class InfoCollectionViewCell : UICollectionViewCell {
@IBOutlet weak var mainPanel : UIView!
@IBOutlet weak var panel1 : UIView!
@IBOutlet weak var firstName : UILabel!
@IBOutlet weak var lastName : UILabel!
@IBOutlet weak var address : UILabel!
etc ...
func setVariousProperties(etc) {
firstName.text = ... etc
Run Code Online (Sandbox Code Playgroud)
数据源通常是这样的:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("InfoCell", forIndexPath:indexPath)
if let c : InfoCollectionViewCell = cell as? InfoCollectionViewCell {
c.setVariousProperties(...)
}
Run Code Online (Sandbox Code Playgroud)
我最初只实现了包含"未实现"断言的解码/编码方法,但很明显,框架偶尔会对类进行编码和解码.我实现了虚拟编码/解码方法,而没有保存组件,在访问组件时导致nil值出现可预测的问题.
所以看来我需要UICollectionViewCell
逐个实现子类中所有控件的编码和解码,或者我必须找到更好的方法.
这似乎是浪费时间,因为我实际上并不需要(我不认为)保存组件的内容,因为它们只是为了子类的重复使用:我将覆盖组件内容将来自数据源的值.
显然,所有控件都在故事板中定义.我可以通过init方法中的storyboard手动从名称中获取它们,但这似乎同样繁琐,并使控件和变量的图形链接变得多余.
有没有更好的办法?
我可以只说"恢复连接"或类似的东西吗?
编辑:
在发布问题和添加赏金之间的某个地方,问题停止发生.我现在注意到我的组件的编码方法没有被调用.因此,由于某种原因,框架决定序列化我的对象并对它们进行反序列化,但现在却没有.因此问题没有发生,我无法提供堆栈跟踪.
可以想象,对XCode的一些更新已经解决了这个问题,或者它可能是其他问题.
我显然仍然担心某处潜伏着一些错误.
encoding reuseidentifier ios uicollectionview uicollectionviewcell
有没有人有关于如何清除缓存的建议UITableViewCell
?
我想用reuseIdentifier缓存这些单元格.但是,有时我需要删除或修改某些表行.我希望reloadData
在行更改后调用.
现在,dequeueReusableCellWithIdentifier
始终返回之前的缓存(过时)条目.如何指示缓存是陈旧的并且需要清除?
我有一个UITableView
和我已经分类UITableViewCell
(称之为CustomCell
)所以它有几个标签和一个UIImageView
.
只有某些单元格才会显示图像.这是我的代码tableView:cellForRowAtIndexPath:
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Match *aMatch = [[appDelegate.matchByDate objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
static NSString *CellIdentifier = @"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.homeLabel.text = aMatch.homeTeam;
cell.awayLabel.text = aMatch.awayTeam;
cell.timeLabel.text = aMatch.koTime;
cell.tournamentLabel.text = aMatch.tournament;
NSString *tempString = [appDelegate.teamLogos objectForKey:[aMatch homeTeam]];
if (tempString!=nil) {
cell.homeImageView.image = [UIImage imageNamed:tempString];
}
return cell;
}
Run Code Online (Sandbox Code Playgroud)
所以它只设置homeImageView …
我正在开发一个带有故事板的iOS 5项目,因此在IB中使用动态表格单元原型.在其中一个视图中,我有一个带有可变高度单元格的表视图,单元格高度根据内容的高度计算.
tableView:heightForRowAtIndexPath:
首次显示表视图时,返回所有单元格的正确值.向下滚动几个项目时一切都很好,但随后出现问题:实际单元格似乎是正确的高度,包括它们的触摸区域,但它们的分隔符在错误的位置(在单元格内而不是它们之间)呈现.
从测量分隔符放置开始,似乎细胞重用可能与此有关.前三个单元格的分隔符正确呈现,但不是第四个.heightForRowAtIndexPath:
为它返回正确的高度(在这种情况下为125像素),其包含的子视图都在正确的位置.但是,分隔符仅从前一个分隔符渲染108个像素,将其放置在单元格的125像素高区域内.
这是踢球者:108px是第一个表格单元格的高度,现在看不见了,可能会重复使用.我没有明确的证据,但似乎表视图忽略heightForRowAtIndexPath:
了这些单元格,只是根据重用的单元格高度渲染分隔符.
这并不能解释为什么一堆较晚的较短单元格根本不会呈现分隔符.但这就是我必须继续下去的全部内容.
是否有解决方法,IB设置或其他可能有帮助的东西?
我已经阅读了这个问题并认为我理解了两种方法之间的区别,直到找到一个奇怪的例子:
设置表格视图单元格的样式为基本,标识符为故事板中的单元格,代码如下:
import UIKit
class TableViewController: UITableViewController {
var items: [String]!
override func viewDidLoad() {
super.viewDidLoad()
items = ["first", "second", "third"]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// either works fine
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! // let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.textLabel?.text = items[indexPath.row]
return …
Run Code Online (Sandbox Code Playgroud) 如果我UITableViewCell
使用reuseidentifier = nil
作为ivar 保持固定并返回特定行的此实例,然后专门使用重新加载此行[tableView reloadRowsAtIndexPaths:withRowAnimation:]
,则行内容消失(或有时闪烁).当我向外滚动并返回时,它再次变得可见.[tableView reloadData]
另一方面,如果我这样做,它就不会消失.
这是一个示例项目:https://github.com/hannesoid/HOTableViewTests
我在iOS 6上对此进行了测试. 我知道通常不推荐以这种方式手动重用UITableViewCell(没有使用useidentifier和dequeueing),但在一些非常静态的情况下,它会简化操作.
reuseidentifier ×10
ios ×7
uitableview ×7
iphone ×2
objective-c ×2
deprecated ×1
encoding ×1
xcode ×1
xcode4 ×1