[Android开发学iOS系列] TableView展现一个list
TableView 基础
本文讲讲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是想展示的数据类型, 可以hardcode一些数据.
这么简单是因为这个ViewController继承了UITableViewController, 并且cell的部分使用了storyboard.
这里需要用dequeueReusableCell方法, 是为了cell的复用, 因为list内容很多的时候cell view是可以循环使用的. (很像Android里的RecyclerView).
UITableViewController的签名是这样:
open class UITableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
它为我们做了以下三件事:
- 设置view为一个
UITableView. - 设置
delegate=self. - 设置
dataSource=self.
这种方式的局限性在于第一点, 它的根view是一个TableView, 如果我们的需求比较复杂, 不仅仅是一个demo, 那么可能需要组合View.
拆解版TableView
我们也可以直接继承UIViewController类, 然后自己动手做上面的几条设置.
Delegate & DataSource
TableView有两个重要的方面需要关注:
- UITableViewDelegate: 管理和用户的交互, 比如选择, 滑动手势等. 没有必须要实现的方法.
- UITableViewDataSource: 提供和管理数据, 包括了数据对应的cell或者header. 有两个必须要实现的方法(如上面的代码例子所示).
继承UIViewController
继承UIViewController而不是UITableViewController之后, 需要自己写一个tableView并加在view里.
再分别实现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的几个原则:
- 方法名以被代理的类型开头.
- 方法的第一个参数是被代理的对象.
References
[Android开发学iOS系列] TableView展现一个list的更多相关文章
- [Android开发学iOS系列] 工具篇: Xcode使用和快捷键
[Android开发学iOS系列] 工具篇: Xcode使用和快捷键 工欲善其事必先利其器. 编辑 Cmd + N: 新建文件 Option + Cmd + N: 新建文件夹 Cmd + / : 注释 ...
- [Android开发学iOS系列] iOS写UI的几种方式
[Android开发学iOS系列] iOS写UI的几种方式 作为一个现代化的平台, iOS的发展也经历了好几个时代. 本文讲讲iOS写UI的几种主要方式和各自的特点. iOS写UI的方式 在iOS中写 ...
- [Android开发学iOS系列] Auto Layout
[Android开发学iOS系列] Auto Layout 内容: 介绍什么是Auto Layout. 基本使用方法 在代码中写约束的方法 Auto Layout的原理 尺寸和优先级 Auto Lay ...
- [Android开发学iOS系列] 语言篇: Swift vs Kotlin
Swift vs Kotlin 这篇文章是想着帮助Android开发快速学习Swift编程语言用的. (因为这个文章的作者立场就是这样.) 我不想写一个非常长, 非常详尽的文章, 只是想写一个快速的版 ...
- [Android开发学iOS系列] ViewController
iOS ViewController 写UIKit的代码, ViewController是离不开的. 本文试图讲讲它的基本知识, 不是很深入且有点杂乱, 供初级选手和跨技术栈同学参考. What is ...
- [Android开发学iOS系列] 快速上手UIKit
快速上手iOS UIKit UIKit是苹果官方的framework, 其中包含了各种UI组件, window和view, 事件处理, 交互, 动画, 资源管理等基础设施支持. 按照前面的介绍, 用U ...
- Android开发—智能家居系列】(二):用手机对WIFI模块进行配置
在实际开发中,我开发的这款APP是用来连接温控器,并对温控器进行控制的.有图为证,哈哈. 上一篇文章[Android开发—智能家居系列](一):智能家居原理的文末总结中写到: 手机APP控制智能温控器 ...
- android开发学习笔记系列(2)-android应用界面编程
前言 本篇博客将会简要介绍andriod开发过程中的一些界面元素和编程的实现,我将大家走进安卓的XML世界,当然可能会涉及到java代码,当然本文主要是介绍XML文件的界面布局. 那么我们的XML存在 ...
- android开发学习笔记系列(1)-android起航
前言 在学习安卓的过程中,我觉得非常有必要将自己所学的东西进行整理,因为每每当我知道我应该是如何去实现功能的时候,有许多细节问题我总是会遗漏,因此我也萌生了写一系列博客来描述自己学习的路线,让我的an ...
- android开发学习笔记系列(4)--android动态布局
前言 在做一个有关苏果APP的项目中,但是fuck的是,我完全使用相对布局之后及线性布局之后发现坑爹的事情了,屏幕不能适配,这是多大的痛,意味着,必须使用相应的代码实现动态布局!呵呵,不做项目不知道, ...
随机推荐
- Python数据科学手册-Numpy入门
通过Python有效导入.存储和操作内存数据的技巧 数据来源:文档.图像.声音.数值等等,将所有的数据简单的看做数字数组 非常有助于 理解和处理数据 不管数据是何种形式,第一步都是 将这些数据转换成 ...
- ELK日志报警插件ElastAlert并配置钉钉报警
文章转载自:https://www.cnblogs.com/uglyliu/p/13118386.html ELK日志报警插件ElastAlert 它通过将Elasticsearch与两种类型的组件( ...
- Prometheus使用nginx 设置二级路径反向代理
1.nginx 设置 location /promethues/ { proxy_pass http://10.xx.xxx.55:9090/prometheus/; } 2.设置prometheus ...
- 第二章:视图层 - 9:动态生成CSV文件
CSV (Comma Separated Values),以纯文本形式存储数字和文本数据的存储方式.纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样的数据.CSV文件由任意数目的记录组成,记 ...
- prometheus和granfana企业级监控实战v5
文件地址:https://files.cnblogs.com/files/sanduzxcvbnm/prometheus和granfana企业级监控实战v5.pdf
- (四)JPA - JQPL 实现增删改查
(一)JPA的快速入门 建议在需要使用时,看看之前的文章,先把环境搭起来. 5.JPQL JPQL和SQL 1.JPQL和SQL很像,查询关键字都是一样的 2.唯一的区别是:JPQL是面向对象的 JP ...
- 02_快捷键及常用DOS命令
快捷键 一. 电脑快捷键 Ctrl + C:复制 Ctrl+ V:粘贴 Ctrl+ A:全选 Ctrl+ S:保存 Ctrl+ Z:撤销 Ctrl+ X:剪切 Alt + F4:关闭窗口 Shift ...
- Linux安装中文字体(已验证)
1.安装字体命令 sudo apt install -y fontconfig 2.查看已安装的字体 (1)查看linux已安装字体 fc-list (2)查看linux已安装中文字体 fc-list ...
- 华为交换机GVRP基础配置
GVRP基础配置 int G0/0/1 port link-type trunk 配置接口类型为trunk port trunk allow-pass vlan all 允许所有VLAN通过 int ...
- 1.ElasticSearch系列之集群部署
第一步:安装JDK JDK要求jdk1.8+,不安装也可以,ES自带JDK 第二步:系统配置 2.1 禁用交换区 sudo swapoff -a 2.2 开最大文件数的限制 编辑文件 /etc/sec ...