带有 UITextView 的单元格的初始滞后
Initial lag for a cell with a UITextView
当前设置
我有一个自定义单元格,从 xib 加载,其中大部分 space 都被 UITextview 覆盖。该单元格也可能有一些文本视图。并且此单元格内还有一些元素(一个 UIView + 2 个 UILabel)。
问题
我尝试删除所有这些视图,即使我只有一个文本视图也仍然存在滞后。此外,延迟只是第一次发生。后来,当我向下滚动并 运行 进入另一个带有文本视图的单元格时,延迟根本不会发生。
附加信息
此自定义单元格的特点是将文本视图添加到 UIStackView
。一开始,stackview 是空的,因为我不知道(在开发时)有多少 textviews may/should 在那里。
我知道这是另一件可能影响性能的事情,但我已经通过检查堆栈视图的 arrangedSubviews
数组中已经找到了多少文本视图来解决了它(我猜是最好的)出列一个单元格,并根据该信息,我只是适当地添加或隐藏视图(而不是每次都销毁并重新创建所需数量的文本视图)。
我尝试过使用 Instruments,但我没有注意到我的任何 classes 占用了 CPU 时间,而是一些 UIKit
方法调用被调用内部框架是造成这种情况的原因...如果需要,我可以 post 截图,但我想这不相关,因为那些似乎是通常的系统和框架调用。另外,我正在 iPad 2 上进行测试:D 所以也许这是一回事(我必须针对慢速设备优化应用程序)。
不过,我想我能以某种方式优化它吗?
MyCellclass比较简单(伪代码):
class MyCell:UITableViewCell{
func configure(data:SomeData){
self.addOrHideViewsIfNeeded()
}
private func addOrHideViewsIfNeeded(){
//here, I check if stackview.arrangedSubviews has, and how many subviews are there, and
//add / hide them appropriately, means if I have to add them, I load them from the nib, otherwise, I reuse views from by adding them/removing them from a pool.
}
}
与 Release 版本相比,Debug 版本的延迟更明显,这是有道理的,但它仍然很明显。
您可能需要检查您是否在重复使用这些单元格。
您可以按如下方式重复使用它:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NAIndexPath *) indexPath{
static NSString *cellIdentifier = @"Mycell";
cell = [tableView dequeueCellWithIdentifier:cellIdentifier];
if(cell == nil)
cell = [[MyCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: cellIdentifier];
}
好的,这是我的想法的草图,即在从用户角度看不可见的表视图第 0 行中进行预加载。
class MyCell : UITableViewCell {
static var initiallyPreloaded : Bool = false
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
if !MyCell.initiallyPreloaded {
//Do the initial preloading setup by adding UITextView to self.contentView
MyCell.initiallyPreloaded = true
} else {
//Setup the regular cell content otherwise
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
class ViewController: UIViewController , UITableViewDelegate {
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell{
var cell: MyCell? = tableView.dequeueReusableCell(withIdentifier: "myCellIdentifier") as! MyCell?
if cell == nil {
cell = MyCell(style: .default, reuseIdentifier: "myCellIdentifier")
}
if indexPath.row == 0 {
//Display the initial cell in unnoticeable to user way (start with hidden/alpha zero)
//For this zero-th row the initial preloading should happen
}
return cell!
}
}
当前设置
我有一个自定义单元格,从 xib 加载,其中大部分 space 都被 UITextview 覆盖。该单元格也可能有一些文本视图。并且此单元格内还有一些元素(一个 UIView + 2 个 UILabel)。
问题
我尝试删除所有这些视图,即使我只有一个文本视图也仍然存在滞后。此外,延迟只是第一次发生。后来,当我向下滚动并 运行 进入另一个带有文本视图的单元格时,延迟根本不会发生。
附加信息
此自定义单元格的特点是将文本视图添加到 UIStackView
。一开始,stackview 是空的,因为我不知道(在开发时)有多少 textviews may/should 在那里。
我知道这是另一件可能影响性能的事情,但我已经通过检查堆栈视图的 arrangedSubviews
数组中已经找到了多少文本视图来解决了它(我猜是最好的)出列一个单元格,并根据该信息,我只是适当地添加或隐藏视图(而不是每次都销毁并重新创建所需数量的文本视图)。
我尝试过使用 Instruments,但我没有注意到我的任何 classes 占用了 CPU 时间,而是一些 UIKit
方法调用被调用内部框架是造成这种情况的原因...如果需要,我可以 post 截图,但我想这不相关,因为那些似乎是通常的系统和框架调用。另外,我正在 iPad 2 上进行测试:D 所以也许这是一回事(我必须针对慢速设备优化应用程序)。
不过,我想我能以某种方式优化它吗?
MyCellclass比较简单(伪代码):
class MyCell:UITableViewCell{
func configure(data:SomeData){
self.addOrHideViewsIfNeeded()
}
private func addOrHideViewsIfNeeded(){
//here, I check if stackview.arrangedSubviews has, and how many subviews are there, and
//add / hide them appropriately, means if I have to add them, I load them from the nib, otherwise, I reuse views from by adding them/removing them from a pool.
}
}
与 Release 版本相比,Debug 版本的延迟更明显,这是有道理的,但它仍然很明显。
您可能需要检查您是否在重复使用这些单元格。
您可以按如下方式重复使用它:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NAIndexPath *) indexPath{
static NSString *cellIdentifier = @"Mycell";
cell = [tableView dequeueCellWithIdentifier:cellIdentifier];
if(cell == nil)
cell = [[MyCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: cellIdentifier];
}
好的,这是我的想法的草图,即在从用户角度看不可见的表视图第 0 行中进行预加载。
class MyCell : UITableViewCell {
static var initiallyPreloaded : Bool = false
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
if !MyCell.initiallyPreloaded {
//Do the initial preloading setup by adding UITextView to self.contentView
MyCell.initiallyPreloaded = true
} else {
//Setup the regular cell content otherwise
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
class ViewController: UIViewController , UITableViewDelegate {
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell{
var cell: MyCell? = tableView.dequeueReusableCell(withIdentifier: "myCellIdentifier") as! MyCell?
if cell == nil {
cell = MyCell(style: .default, reuseIdentifier: "myCellIdentifier")
}
if indexPath.row == 0 {
//Display the initial cell in unnoticeable to user way (start with hidden/alpha zero)
//For this zero-th row the initial preloading should happen
}
return cell!
}
}