一、UITableView是什么?

UITableView是一个强壮的视图组件,它能够显现一个翻滚的列表数据。每个列表项被称为一个单元格(UITableViewCell)。UITableView的数据源(通常是一个数组)和托付(通常是视图控制器)供给了列表的内容和行为。

二、UITableView什么作业原理?

理解UITableView的作业原理关于优化其功能和用户体会至关重要。当你翻滚表格时,UITableView并不会为一切单元格创立视图。相反,它运用了一种叫做“单元格重用”的技术,只创立屏幕上可见的单元格,并且当这些单元格翻滚出屏幕时,会将其放入一个重用队列中。当新的单元格翻滚到屏幕上时,UITableView会从重用队列中取出一个单元格,并对其进行配置。这便是为什么在cellForRowAt办法中,你总是需求配置单元格的一切特点——由于你无法确定这个单元格是新的,还是从重用队列中取出的。

三、 UITableView如何优化?

了解完上面的作业原理,咱们就能够从以下几个方面进行优化

●重用单元格

●异步加载图片

●预估单元格高度

●防止离屏烘托

●防止图片尺寸不一致

●防止动态增加内容

●滑动按需加载

1. 重用单元格

在UITableView中,单元格的重用是进步功能的要害。经过重用单元格,咱们能够防止频频地创立和销毁单元格方针,然后削减内存分配和开释的开支。

要完成单元格的重用,咱们需求注册单元格的重用标识符,并在cellForRowAtIndexPath办法中运用dequeueReusableCellWithIdentifier办法获取可重用的单元格。下面是一个简略的示例:

//注册单元格的重用标识符
tableView.register(UITableViewCell.self,forCellReuseIdentifier: "cell")  
//在cellForRowAtIndexPath办法中获取可重用的单元格
func tableView(_tableView: UITableView,cellForRowAtindexPath: IndexPath) -> UITableViewCell {  
    letcell=tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)  
    //配置单元格的数据和界面
    returncell
}

2. 异步加载图片

在UITableView中加载图片时,假如图片较大或许网络加载较慢,可能会导致翻滚卡顿。为了解决这个问题,咱们能够运用异步加载图片的办法。

异步加载图片的中心思维是在后台线程中加载图片,然后在主线程中更新UI。这样能够防止阻塞主线程,进步翻滚的流畅性。下面是一个运用SDWebImage库进行异步加载图片的示例:

func tableView(_tableView: UITableView,cellForRowAtindexPath: IndexPath) -> UITableViewCell {
    letcell=tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)  
    letimageUrl= ""  
cell.imageView?.sd_setImage(with: URL(string:imageUrl),placeholderImage: UIImage(named: "placeholder"))  
    returncell
}

3. 预估单元格高度

当UITableView包括可变高度的行时,假如逐行核算高度,会导致功能开支巨大,由于这种办法需求对每一行进行高度核算,然后增加了CPU和GPU的担负。因而为了优化功能,能够运用estimatedRowHeight特点来为单元格设置预估高度。

estimatedRowHeight特点答应您为UITableView设置一个估量的行高,以便在加载表格时预先分配足够的空间,而不需求逐行核算高度。经过运用estimatedRowHeight特点,您能够防止因逐行核算高度而产生的功能瓶颈,然后进步表格的翻滚功能和响应速度。

需求留意的是,estimatedRowHeight只是一种估量值,实践行高可能会依据内容的不同而有所差异。因而,在运用estimatedRowHeight时,您需求依据表格中内容的特性和规律来选择一个适宜的估量值,以确保表格的显现作用和功能达到一个良好的状态。

tableView.estimatedRowHeight=10.0f;//预估行高度

4. 防止离屏烘托

运用圆角、暗影等视图功能的时候,会进行离屏烘托,而离屏烘托跟当时屏幕烘托又不同。它会单独拓荒一块缓冲区进行烘托操作,这个进程相对较耗资源。

(1)关于圆角较好的做法是让美术供给圆角背景图,并给Cell设成背景图片。

(2)关于暗影作用能够经过以下代码设置

import UIKit
extension UIImageView {  
    func addShadow() {  
layer.masksToBounds= false  
layer.shadowColor= UIColor.black.cgColor
layer.shadowOffset= CGSize(width: 0,height: 0)  
layer.shadowOpacity= 0.5  
layer.shadowRadius= 2  
layer.shadowPath= UIBezierPath(rect:bounds).cgPath
    }  
}

5.防止图片尺寸不一致

为了进步UITableView的功能,图片的尺寸应该与UIImageView的尺寸保持一致。经过将图片的尺寸调整为与UIImageView的尺寸相同,能够防止不必要的缩放和拉伸,然后削减核算资源和内存的占用。

此外,图片的contentMode也会对UITableView的翻滚速度形成影响。假如图片的contentMode不正确,可能会导致图片加载速度变慢,然后影响应用程序的功能。因而,需求依据需求显现的图片大小来处理contentMode,以优化图片的显现作用。

5. 防止动态增加内容

在初始化UITableViewCell时,将一切需求展现的子视图增加到cell中,防止动态增加。这些子视图能够是自定义的UI元素,例如文本标签、图画视图、按钮等。

优化办法:增加子视图后,能够依据需求设置它们的躲藏特点,以控制它们的显现和躲藏。

经过在初始化时将一切子视图增加到cell中,能够确保它们在显现时现已存在,并且能够在需求时轻松地显现或躲藏它们。这种办法适用于在cell中展现动态内容的情况,例如依据数据源动态设置不同的视图内容。

需求留意的是,假如在初始化时增加了过多的子视图,可能会占用额定的内存和核算资源。因而,在增加子视图时应该考虑到这一点,并依据需求合理地办理内存和核算资源的运用。

6. 滑动按需加载

滑动按需载可分为两种:

●分页加载

分页加载是指当用户翻滚到UITableView底部时,自动加载下一页数据。这能够经过监听UITableView的翻滚事情来完成。以下是一个示例代码:

funcscrollViewDidScroll(_scrollView:UIScrollView){
letoffsetY=scrollView.contentOffset.y
letcontentHeight=scrollView.contentSize.height
letscrollViewHeight=scrollView.frame.height
ifoffsetY>contentHeight-scrollViewHeight{
//加载下一页数据
loadNextPageData()
}
}

●滑动范围加载

滑动范围前后加载是指只在方针翻滚范围的前后指定3行加载。这么处理是由于用户在快速滑动的进程中,大量快速滑动的内容是无用的。所以咱们只需求加载最后滑动范围的内容即可。

//按需加载-假如方针行与当时行相差超过指定行数,只在方针翻滚范围的前后指定3行加载。
func scrollViewWillEndDragging(_scrollView: UIScrollView,withVelocityvelocity: CGPoint,targetContentOffset: UnsafeMutablePointer<CGPoint>) {  
    //获取方针偏移量对应的索引途径
    letip= indexPathForRow(at: CGPoint(x: 0,y:targetContentOffset.pointee.y))  
    //获取当时可见的第一个索引途径
    if letcip=indexPathsForVisibleRows?.first {  
        letskipCount= 10 //指定行数
        //假如方针行与当时行相差超过指定行数
        if abs(cip.row-ip.row) >skipCount{  
            //获取方针翻滚范围内的一切索引途径
            lettemp= indexPathsForRows(in: CGRect(x: 0,y:targetContentOffset.pointee.y,width: self.width,height: self.height))  
            vararr=tempas NSArray as? [IndexPath] ?? []  
            //假如翻滚方向是向上
            ifvelocity.y< 0 {  
                if letindexPath=temp.last,indexPath.row> 3 {  
                    //在方针翻滚范围前增加3个索引途径
arr.append(IndexPath(row:indexPath.row-3,section: 0))  
arr.append(IndexPath(row:indexPath.row-2,section: 0))  
arr.append(IndexPath(row:indexPath.row-1,section: 0))  
                }  
            }  
            //将需求加载的数据增加到数组中
            self.needLoadDatas.append(contentsOf:arr)  
        }  
    }  
}

四、 总结

本文介绍UITableView功能优化的思路,在具体的业务应用中,可能会面对不同的场景和不同的需求,需求具体问题具体分析,但万变不离其中,假如大家有其它优化思路、疑问或许复杂场景,欢迎谈论区一同交流~