[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的是,我完全使用相对布局之后及线性布局之后发现坑爹的事情了,屏幕不能适配,这是多大的痛,意味着,必须使用相应的代码实现动态布局!呵呵,不做项目不知道, ...
随机推荐
- HDFS 分布式环境搭建
HDFS 分布式环境搭建 作者:Grey 原文地址: 博客园:HDFS 分布式环境搭建 CSDN:HDFS 分布式环境搭建 准备四个Linux实例 每个实例对应的 host 和 ip 地址如下 nod ...
- csp每日习题
欢迎加入:qq群号:1054587486 做题链接:https://csp.ccf.org.cn/csp/index.action?_access_code=1584494752035 点击模拟考试进 ...
- 面向制造企业普适性ERP、MES类产品为什么那么难找?
标准化与个性化之间的矛盾怎么可能通过普适性的ERP.MES系统来解决?为什么难?就跟你找一套适合所有人穿的衣服一样难,事实上这个比找衣服更难!人与人之间高矮胖瘦各不相同.肤色体型各有差异,把同一套衣服 ...
- PHP全栈开发(八):CSS Ⅹ 导航栏制作
学习了这么久的CSS,我们现在也可以小试牛刀一下了,我们使用我们学会的CSS知识来制作一个导航栏. 我们都知道,在现代的导航栏里面,最普遍的就是使用无序列表来制作导航栏. 我们可以使用如下代码来制作一 ...
- 记一次某制造业ERP系统 CPU打爆事故分析
一:背景 1.讲故事 前些天有位朋友微信找到我,说他的程序出现了CPU阶段性爆高,过了一会就下去了,咨询下这个爆高阶段程序内部到底发生了什么? 画个图大概是下面这样,你懂的. 按经验来说,这种情况一般 ...
- 非Navicat破解延长14天试用时间
延长Navicat使用时长 Navicat作为一套多连接数据库开发工具,十分好用,购买正版太过昂贵,破解版过于麻烦,有时候还会有安全问题,好在我们有14天的试用时间,我们可以从这个方面入手 对于有能力 ...
- map集合类型/实体类类型的参数
map集合类型的参数 若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合, 将这些数据放在map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要 ...
- 路由组件构建方案(分库分表)V1
路由组件构建方案V1 实现效果:通过注解实现数据分散到不同库不同表的操作. 实现主要以下几部分: 数据源的配置和加载 数据源的动态切换 切点设置以及数据拦截 数据的插入 涉及的知识点: 分库分表相关概 ...
- 齐博X1-栏目的终极方法get_sort
本节说明栏目的最终方法get_sort 我们之前讲的一系列fun函数调用栏目的方法都是基于get_sort这个公共方法而来 我们来看下这个函数的具体参数这个方法有四个参数: id:也就是栏目id,经常 ...
- 齐博x1客服系统显示客户在哪个页面
如下图所示,要想实现下面的效果,即显示客户给你发消息时,当时处于哪个商品页面.这样方便跟客户针对此商品进行交流. 你的模板如果使用了碎片的话,就可以添加下面的代码index_style/default ...