Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 带UITableViewCells的UITableView+;自动布局-不如*应该*的平滑_Ios_Swift_Autolayout_Uitableview - Fatal编程技术网

Ios 带UITableViewCells的UITableView+;自动布局-不如*应该*的平滑

Ios 带UITableViewCells的UITableView+;自动布局-不如*应该*的平滑,ios,swift,autolayout,uitableview,Ios,Swift,Autolayout,Uitableview,我最近发布了一个关于自定义UITableCells的UITableView的问题,该问题在使用AutoLayout定位单元格的子视图时不平滑。我收到一些评论,认为缺乏平滑是由于单元格的复杂布局。虽然我同意单元格布局越复杂,tableView计算单元格高度的次数就越多,但我不认为10-12 UIView和UILabel子视图会造成我在iPad上滚动时看到的延迟量 因此,为了进一步证明我的观点,我创建了一个UIViewController项目,其中包含一个UITableView子视图和自定义UITa

我最近发布了一个关于自定义UITableCells的UITableView的问题,该问题在使用AutoLayout定位单元格的子视图时不平滑。我收到一些评论,认为缺乏平滑是由于单元格的复杂布局。虽然我同意单元格布局越复杂,tableView计算单元格高度的次数就越多,但我不认为10-12 UIView和UILabel子视图会造成我在iPad上滚动时看到的延迟量

因此,为了进一步证明我的观点,我创建了一个UIViewController项目,其中包含一个UITableView子视图和自定义UITableViewCells,它们的子类中只有两个标签。而且滚动仍然不是完全平滑的。从我的角度来看,这是你能得到的最基本的东西——因此,如果UITableView仍然不能用这种设计实现,那么我肯定错过了什么

下面使用的110的
估计值与实际行高平均值非常接近。当我使用“用户界面检查器”逐个查看每个单元格的高度时,它们的范围是103-124

请记住,当我将下面的代码切换为不使用
estimatedRowHeight
UITableViewAutomaticDimension
时,而是实现
func tableView(tableView:UITableView,heightForRowAtIndexPath:NSIndexPath)->CGFloat{
,使用帧值计算高度,UITableView会像黄油一样滚动

应用程序屏幕截图(供参考)

应用程序的源代码(滚动不完全平滑)

我喜欢下面matt的建议,但我仍在尝试调整它以适合我:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var cellHeights: [CGFloat] = [CGFloat]()

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if cellHeights.count == 0 {
            var cellHeights = [CGFloat]()
            let numQuotes: Int = dataItems.count

            for index in 0...numQuotes - 1 {
                let cell = CellQuote()
                let quote = dataItems[index]

                cell.configureWithData(quote)
                let size = cell.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
                cellHeights.append(size.height)
            }

            self.cellHeights = cellHeights
        }

        return self.cellHeights[indexPath.row]

    }
}

两个文本标签的清晰背景会导致性能问题。添加这些行,您将看到性能提高:

labelText.backgroundColor = containerView.backgroundColor
labelAuthor.backgroundColor = containerView.backgroundColor
检查任何其他潜在问题的一个好方法是在iOS模拟器的“调试”菜单选项中打开“颜色混合层”

更新

通常,我对动态单元高度所做的是创建一个原型单元,并使用它进行大小调整。以下是您在这种情况下的操作:

class CellQuote: UITableViewCell {
    private static let prototype: CellQuote = {
        let cell = CellQuote(style: .Default, reuseIdentifier: nil)
        cell.contentView.translatesAutoresizingMaskIntoConstraints = false
        return cell
    }()

    static func heightForQuote(quote: Quote, tableView:UITableView) -> CGFloat {
        prototype.configureWithData(quote)
        prototype.labelText.preferredMaxLayoutWidth = CGRectGetWidth(tableView.frame)-40
        prototype.labelAuthor.preferredMaxLayoutWidth = CGRectGetWidth(tableView.frame)-40

        prototype.layoutIfNeeded();
        return CGRectGetHeight(prototype.contentView.frame)
    }

    // existing code here
}
在您的视图中,删除行高和估计的行宽线,并替换为成为代理

class ViewController {
    override func viewDidLoad() {
        // existing code

        self.tableView.delegate = self

        // existing code
    }

    // get prototype cell height
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let quote = dataItems[indexPath.row]
        return CellQuote.heightForQuote(quote, tableView: tableView)
    }

我从未发现自动行高机制像自动布局出现之前我们使用的旧的计算布局技术那样平滑。通过使用工具,您可以很容易地看到,瓶颈在于运行时必须在滚动到视图中的每个新单元格上调用
systemLayoutSizeFittingSize:


在我的书中,我演示了我的首选技术,即在第一次出现表视图时计算所有单元格的高度。这意味着从那时起,我可以立即为
heightforrowatinexpath
提供答案,从而尽可能获得最佳的用户体验。此外,如果您随后替换对
deque的调用ueReusableCellWithIdentifier
使用更好、更现代的
DEQUEEREUSABLECELLWITHIDENTIFIER:forIndexPath
,您的优势是单元格大小正确,此后无需进一步布局。

谢谢@Casey,我添加了这些行来给标签的背景上色,但没有看到m差异太大了。现在要运行颜色混合层。当我打开颜色混合层时,我的TableView中的所有内容都是绿色的。唯一的红色内容是状态栏的文本(载波、Wifi、时间和电池),和我滚动时右侧的滚动条指示器。耶,添加这两行后,它应该都是绿色的。顺便说一句,您的代码不编译,不编辑quote Stringssory@Casey,我尝试为quote字符串输入新行以使其更具可读性,但我必须使用多行字符串将其打断。我的错误,将更新。这工作!看看我现在是否可以将它与一些缓存机制结合起来!这对我来说很好-@matt,当表格视图首次出现时,我如何计算所有单元格的高度,我很想知道如何!我将缓存高度,然后在
heightforrowatinexpath
函数中完全使用它们。我将查看deqUEUEUERUSABLECELLWITHIDENTIFIER:forIndexPath也是!我实现了您的解决方案,但出于某种原因,我的所有单元格都以相同的高度返回。我假设这与我的
setUpCell:forIndexPath
函数有关,我将该函数保留为我的
configureWithData(quote:quote)函数
。我将您建议的
heightforrowatinexpath
的实现复制到上面的原始问题中。
class ViewController {
    override func viewDidLoad() {
        // existing code

        self.tableView.delegate = self

        // existing code
    }

    // get prototype cell height
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let quote = dataItems[indexPath.row]
        return CellQuote.heightForQuote(quote, tableView: tableView)
    }