序言
UITableView 是开发中常用的控件,掌握 UITableView 的相关知识点至关重要,本文针对 UITableView 在Swift语法中的学习总结。仅个人学习笔记!
UITableViewCell
- UITableView由UITableViewCell组成,UITabelViewCell负责显示数据
- UITableViewCell对象的数量不受限制,仅由设备内存决定
- UITableViewCell类定义了单元格在UITableView中的属性和行为
系统预定义的cell提供了4种样式:
-
.default:
-
.value1:
-
.value2:
-
.subtitle:
UITableView
1.样式
- .plain:展示单组数据,没有分组
- .grouped:展示多组数据,有分组,每一组可以有不同的行数
2.创建TableView
创建UITableView,首先是实例化一个UITableView对象,还要涉及到它的代理UITabelViewDataSource、UITableViewDelegate在UITableViewDataSource代理方法中定义UITableViewCell的样式。
import UIKit
///遵守协议
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
let tableView = UITableView(frame: view.bounds, style: .grouped)
//设置数据源对象、代理
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
}
//MARK:UITableViewDataSource
///cell的个数
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
///cell的内容
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellID = "testCellID"
var cell = tableView.dequeueReusableCell(withIdentifier: cellID)
if cell == nil {
cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellID)
}
cell?.textLabel?.text = "textLabel"
cell?.detailTextLabel?.text = "detailTextLabel"
cell?.imageView?.image = UIImage(named: "image")
return cell!
}
//MARK:UITableViewDelegate
///设置行高
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
///选中cell执行此方法
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.row)
}
}
3. UITableViewDataSource数据源方法
1.设置某个section中cell的数量,必须实现
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
2.初始化和复用指定索引位置的UITableViewCell,设置cell内容。必须实现
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
3.设置表格中section的个数
func numberOfSections(in tableView: UITableView) -> Int
4.设置section的头部标题文字,如果不设置或代理返回值为nil,不显示
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
5.设置section脚部标题文字,如果不设置或代理返回值为nil,不显示
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?
6.设置表格中指定索引位置的cell是否可编辑,可编辑的cell会显示插入和删除的图标。
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
7.当完成插入或删除操作时会调用此方法
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
8.设置指定索引位置的cell是否可以通过拖动的方式,改变它的位置。
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
9.当cell从一个位置拖动到另一个位置时调用此方法。
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
4.UITableViewDelegate代理方法
1.设置单元格高度,每当表格需要显示时,都会调用此方法
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
2.设置某一索引下的章节头部的高度
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
3.设置某一索引下的章节尾部的高度
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
4.当指定索引位置上的单元格即将显示时,调用此方法。此方法是委托对象有机会在单元格显示之前重写其状态属性,如背景颜色等
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
5.当用户点击选择指定索引位置的单元格时,调用此方法
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
6.当用户点击一个已经被选中的单元格时,调用此方法
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
5.UITableView重用机制
一个UITableView可能需要显示多条数据,但屏幕有限。UITableView采用重用机制,系统只创建屏幕可见的UITableViewCell对象,当滑动超出屏幕,系统进行回收重用。
dequeueReusableCell方法的作用是从单元格对象池中获取指定类型并可复用的单元格对象
let cellID = "testCellID"
var cell = tableView.dequeueReusableCell(withIdentifier: cellID)
如果从对象池中没有获得可复用的单元格,就调用实例化方法实例一个某一类型的、可复用的单元格
if cell == nil {
cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellID)
}
- style参数: 枚举常量,用于表示单元格的样式
- reuseIdentifier: 作为一个字符串类型的参数,它用来标识具有相同类型的、可复用的单元格。对于相同类型的单元格,需要使用相同的reuseIdentifier参数。
6.自定义UITableViewCell
对于相对复杂一些的显示内容,我们会创建一个UITableViewCell的类文件,例如以下创建TYNormalTableViewCell文件继承自UITableViewCell
TYNormalTableViewCell.swift
import UIKit
class TYNormalTableViewCell: UITableViewCell {
var titleLabel:UILabel! ///标题
var sourceLabel:UILabel! ///内容
var commentLabel:UILabel! ///评论
var timeLabel:UILabel! ///时间
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
///标题
titleLabel = UILabel(frame: CGRect(x: 20, y: 15, width: 300, height: 50))
// titleLabel.backgroundColor = UIColor.red
titleLabel.font = UIFont.systemFont(ofSize: 16)
titleLabel.textColor = UIColor.black
///内容
sourceLabel = UILabel(frame: CGRect(x: 20, y: 80, width: 50, height: 20))
// sourceLabel.backgroundColor = UIColor.orange
sourceLabel.font = UIFont.systemFont(ofSize: 12)
sourceLabel.textColor = UIColor.gray
///评论
commentLabel = UILabel(frame: CGRect(x: 100, y: 80, width: 50, height: 20))
// commentLabel.backgroundColor = UIColor.yellow
commentLabel.font = UIFont.systemFont(ofSize: 12)
commentLabel.textColor = UIColor.gray
///时间
timeLabel = UILabel(frame: CGRect(x: 150, y: 80, width: 50, height: 20))
// timeLabel.backgroundColor = UIColor.green
timeLabel.font = UIFont.systemFont(ofSize: 12)
timeLabel.textColor = UIColor.gray
contentView.addSubview(titleLabel)
contentView.addSubview(sourceLabel)
contentView.addSubview(commentLabel)
contentView.addSubview(timeLabel)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func layoutSubviews() {
titleLabel.text = "自定义UItableViewCell"
sourceLabel.text = "Swift语言"
sourceLabel.sizeToFit()
commentLabel.text = "231评论"
commentLabel.sizeToFit()
commentLabel.frame = CGRect(x: sourceLabel.frame.origin.x + sourceLabel.frame.width + 15.0, y: commentLabel.frame.origin.y, width: commentLabel.frame.width, height: commentLabel.frame.height)
timeLabel.text = "3分钟前"
timeLabel.sizeToFit()
timeLabel.frame = CGRect(x: commentLabel.frame.origin.x + commentLabel.frame.width + 15.0, y: timeLabel.frame.origin.y, width: timeLabel.frame.width, height: timeLabel.frame.height)
}
}
TYNewsViewController
import UIKit
class TYNewsViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
///创建Tableivew
creatTableivew()
}
func creatTableivew(){
let tableView = UITableView(frame: view.bounds)
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellID = "testID"
var cell:TYNormalTableViewCell? = tableView.dequeueReusableCell(withIdentifier: cellID) as? TYNormalTableViewCell
if cell == nil {
cell = TYNormalTableViewCell(style: .subtitle, reuseIdentifier: cellID)
}
cell?.layoutSubviews()
return cell!
}
///设置行高
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
实现结果如图所示
注: 写代码写了如下错误,反复纠结半小时
错误提示:- Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
控制台:Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
网友评论