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