TableView 仅加载可见单元格(12 个部分表视图中的前 4 个部分)

Posted

技术标签:

【中文标题】TableView 仅加载可见单元格(12 个部分表视图中的前 4 个部分)【英文标题】:TableView only loading visible cells (top 4 sections out of 12 section table view) 【发布时间】:2016-09-11 01:29:36 【问题描述】:

我试图弄清楚为什么我的 tableView 只呈现在调用 viewDidAppear 方法时对用户可见的部分。

当我第一次启动应用程序时,第 1、2 和 3 部分正确呈现,如下所示。但是,第 4 节及以后的部分无法正确呈现。当我按下刷新按钮(手动调用 reload() 方法)时,单击刷新按钮期间的可见部分会刷新并正确呈现。

我已将我的 viewDidAppear 方法以及一个临时的“刷新”按钮链接到下面的 reload() 方法:

    textViewArray = [m1DF,m2DF,m3DF,m4DF,m5DF,m6DF,m7DF,m8DF,m9DF,m10DF,m11DF,m12DF,m13DF,m14DF,m15DF,m16DF]

    for (index, tv) in textViewArray!.enumerate() 
        let fixedWidth = tv.frame.size.width
        tv.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
        let newSize = tv.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
        var newFrame = tv.frame
        newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
        tv.frame = newFrame;
        heightArray[index] = newSize.height
    

    for (index, _) in (heightArray.enumerate()) 
        heightArray[index] = textViewArray![index].frame.height

    
    self.tableView.reloadData()

当我第一次启动应用程序时,第 1、2 和 3 部分正确呈现,如下所示:

但是,第 4 节及以后的部分无法正确呈现:

当我按下刷新按钮(手动调用 reload() 方法)时,单击刷新按钮期间的可见部分(在本例中为标题为“M05”和“M06”的部分)刷新并正确呈现:

编辑

不包括网点的完整代码:

导入 UIKit 导入广告支持 导入 iAd

class CalculatorTableViewController: UITableViewController 

    var heightArray: [CGFloat] = [44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0,44.0]

    var textViewArray = [UITextView]?()

    override func viewDidAppear(animated: Bool) 
        super.viewDidAppear(animated)
        reload()
    



    func reload() 

        textViewArray = [m1DF,m2DF,m3DF,m4DF,m5DF,m6DF,m7DF,m8DF,m9DF,m10DF,m11DF,m12DF,m13DF,m14DF,m15DF,m16DF]
        print("*****1*****\n\n\n\n\n \(m1DF.bounds.height), \(m1DF.frame.height)")

        for (index, tv) in textViewArray!.enumerate() 
            let fixedWidth = tv.frame.size.width
            tv.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
            let newSize = tv.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
            var newFrame = tv.frame
            newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
            tv.frame = newFrame;
            heightArray[index] = newSize.height
            print("Row \(index) has height \(newSize.height)")
        

        for (index, _) in (heightArray.enumerate()) 
            heightArray[index] = textViewArray![index].frame.height

        
        self.tableView.reloadData()
    

    override func viewDidLoad() 
        super.viewDidLoad()

    

    override func viewDidLayoutSubviews() 
        super.viewDidLayoutSubviews()

    

    override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) 

        //sizeCell(indexPath.section)
    

    @IBAction func refreshButton(sender: AnyObject) 

        reload()



    

    override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
        return 300.0
    

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
        if indexPath.row == 0 
            return heightArray[indexPath.section]
         else 
            return UITableViewAutomaticDimension
        
    

    /*override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 
        return 200.0
    */




【问题讨论】:

@vikingsegundo 你这是什么意思? 如果您查看文档,您会发现表格视图旨在仅呈现可见单元格。为什么要对可能永远不会显示的单元格进行可能昂贵的渲染?您的问题来自未正确实现数据源和委托。 我的问题是,即使用户清楚地看到下面的单元格,它也不会渲染它们。他们只有在我使用刷新按钮强制他们渲染时才会渲染。 正如我所说:您的数据源和委托存在问题。猜猜看:只要您不显示代码,我们就帮不了您。 在上面添加了我的代码... 【参考方案1】:

查看您的代码,我认为您对在 UIKit 中实现表格视图的关键原则感到困惑。这可能会令人生畏,我一开始肯定会感到困惑!您应该查看以下参考: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/cl/UITableView 这更详细地概述了我将要谈论的一些事情。 本质上,UiTableViewController 需要做两件事:首先,它需要知道从哪里获取数据以填充表格;其次,它需要知道如何以您想要的方式将表格组合在一起并将其呈现给用户。 对于这些任务中的第一个 - 将其称为数据任务,它实际上非常简单。您只需要确保表视图控制器可以访问封装了您需要的所有数据的数据对象。也有一个专门的协议——UITableViewDataSource——但你不需要这么复杂。我已经实现了表,从字符串数组到使用在更高维度上工作的专用数据管理器类。

这些任务中的第二个 - 称之为演示任务 - 可能更令人困惑。配置表格视图的方式是通过与 UITableViewController 对象一起打包的委托方法(因为它默认是表格视图的委托)。

也许其中最重要的是:cellForRowAtIndexPath:。此函数告诉视图在表中的每个索引路径放置什么。您使用委托函数中提供的索引路径来定位您需要的数据(例如,cell.text = stringData[indexPath.row] 在一个简单的情况下),然后您可以定制视图和任何子视图以呈现该数据作为您会想要。我假设你知道如何做到这一点。实现 cellForRowAtIndexPath: 可能会出现问题的一件事是,您需要重新使用已出列的单元格,而不是每次需要时都创建一个新单元格。你这样做的方法是:首先,通过调用 registerClass:forCellReuseIdentifier 告诉表视图控制器你正在为你的可重用单元格使用哪个类。在标准情况下,您要注册的类是 UiTableViewCell,但您也可以使用自己的类。然后,您可以通过调用 dequeueReusableCellWithIdentifier 来获取其中一个单元格(这将是一个不再使用的单元格,即它已从屏幕上滚动)。

您需要的另一个关键函数是: numberOfRowsInSection(_ section: Int) 告诉控制器表的每个部分有多少行(如果只有一个部分,它当然是表中的行数)。您可以在初始化表格时将其与 UITableView 变量 numberOfSections 和 UITableView rowHeight 一起使用以设置这些基本参数。

综上所述,无需为表中的每一行设置高度(就像您使用的数组一样),也无需显式的 reload() 函数 - 有一个函数“内置”来执行此操作,它只需调用我已经提到的方法。

为了不让这篇文章成为我写的最长的帖子之一,我会把它留在那里!但是,如果您希望我发送一些示例代码,我会很乐意这样做,尽管您最好尝试一下我上面简要概述的内容 - 希望对您有所帮助!

【讨论】:

以上是关于TableView 仅加载可见单元格(12 个部分表视图中的前 4 个部分)的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 仅加载在设备上可见的自定义单元格,并在添加更多单元格时崩溃

tableView 单元格高度...如何自定义?

快速Xcode中的部分和单元格

如何在iOS,Objective C的tableview中的每个部分中仅实现单个单元格选择

限制tableView中显示的单元格数量,滚动到最后一个单元格时加载更多单元格

如何像加载单元格一样动态加载节标题