網(wǎng)站首頁 編程語言 正文
TableView 基礎(chǔ)
本文講講TableView的基本使用. 順便介紹一下delegation.
TableView用來做什么
TableView用來展示一個很長的list. 和Android中的RecyclerView不同, iOS中的TableView只能是豎直方向的list.
如何寫一個最簡單的TableView
一個最簡單的TableViewController看起來像這樣:
class ViewController: UITableViewController { var data: [String] = [] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // loadData() print(data) } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { data.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) cell.textLabel?.text = data[indexPath.row] return cell } }
這里data是想展示的數(shù)據(jù)類型, 可以hardcode一些數(shù)據(jù).
這么簡單是因為這個ViewController繼承了UITableViewController
, 并且cell的部分使用了storyboard.
這里需要用dequeueReusableCell
方法, 是為了cell的復(fù)用, 因為list內(nèi)容很多的時候cell view是可以循環(huán)使用的. (很像Android里的RecyclerView).
UITableViewController
的簽名是這樣:
open class UITableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
它為我們做了以下三件事:
- 設(shè)置view為一個
UITableView
. - 設(shè)置
delegate=self
. - 設(shè)置
dataSource=self
.
這種方式的局限性在于第一點, 它的根view是一個TableView, 如果我們的需求比較復(fù)雜, 不僅僅是一個demo, 那么可能需要組合View.
拆解版TableView
我們也可以直接繼承UIViewController
類, 然后自己動手做上面的幾條設(shè)置.
Delegate & DataSource
TableView有兩個重要的方面需要關(guān)注:
- UITableViewDelegate: 管理和用戶的交互, 比如選擇, 滑動手勢等. 沒有必須要實現(xiàn)的方法.
- UITableViewDataSource: 提供和管理數(shù)據(jù), 包括了數(shù)據(jù)對應(yīng)的cell或者header. 有兩個必須要實現(xiàn)的方法(如上面的代碼例子所示).
繼承UIViewController
繼承UIViewController而不是UITableViewController
之后, 需要自己寫一個tableView并加在view里. 再分別實現(xiàn)UITableViewDelegate
和UITableViewDataSource
, 這里寫在extension里, 拆分完之后set給tableView:
tableView.delegate = self tableView.dataSource = self
整體改造后代碼如下:
class ViewController: UIViewController { var data: [String] = ["Hello", "World"] private let tableView = UITableView() override func loadView() { view = UIView() view.addSubview(tableView) tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.topAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), ]) } override func viewDidLoad() { super.viewDidLoad() tableView.register(MyCell.self, forCellReuseIdentifier: "MyCell") tableView.delegate = self tableView.dataSource = self } } extension ViewController: UITableViewDelegate {} extension ViewController: UITableViewDataSource { func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { data.count } func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as? MyCell { cell.configure(with: data[indexPath.row]) return cell } return UITableViewCell() } }
自己的Cell class
這里Cell也改用代碼類, 寫一個這樣的類:
class MyCell: UITableViewCell { private let label = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(label) label.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ label.topAnchor.constraint(equalTo: contentView.topAnchor), label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), ]) } @available(*, unavailable) required init?(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } func configure(with data: String) { label.text = data } }
注意tableView注冊這個Cell類型:
override func viewDidLoad() { super.viewDidLoad() tableView.register(MyCell.self, forCellReuseIdentifier: "MyCell") }
補充知識: Delegation
上面的方法初看可能會非常怪. 這里還涉及到了一個知識點是iOS中的delegate. 它存在的意義是為了拓展本身類的功能.
Apple自己的很多API就用了delegate protocol, 比如UIApplicationDelegate
, UITableViewDelegate
. 如果我們想自己定義一個:
protocol MyTypeDelegate: AnyObject { func myType(_ myType: MyType, shouldDoSomething argumentString: String) -> Bool func myType(_ myType: MyType, didAbortWithError error: Error) func myTypeDidFinish(_ myType: MyType) } class MyType { weak var delegate: MyTypeDelegate? }
定義delegation的幾個原則:
- 方法名以被代理的類型開頭.
- 方法的第一個參數(shù)是被代理的對象.
References
Filling a table with data
Table View Guide
原文鏈接:https://juejin.cn/post/7168500107095048199
相關(guān)推薦
- 2023-08-15 antdv Input組件maxLength屬性設(shè)置默認值
- 2022-12-10 Android入門之計時器Chronometer的使用教程_Android
- 2022-07-23 深度解析C語言中數(shù)據(jù)的存儲_C 語言
- 2021-12-16 詳細講解HTTP協(xié)議工作方式_相關(guān)技巧
- 2022-06-20 go語言實現(xiàn)屏幕截圖的示例代碼_Golang
- 2022-07-12 jmm內(nèi)存模型及volatile實現(xiàn)原理
- 2022-09-07 C語言函數(shù)調(diào)用堆棧詳情分析_C 語言
- 2023-07-16 uniapp 小程序訂閱消息報錯( wx.requestSubscribeMessage is no
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支