[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的是,我完全使用相对布局之后及线性布局之后发现坑爹的事情了,屏幕不能适配,这是多大的痛,意味着,必须使用相应的代码实现动态布局!呵呵,不做项目不知道, ...
随机推荐
- ProxySQL Cluster 高可用集群 + MySQL MGR环境部署 (多写模式) 部署记录
文章转载自:https://blog.51cto.com/u_6215974/4937192 ProxySQL 在早期版本若需要做高可用,需要搭建两个实例,进行冗余.但两个ProxySQL实例之间的数 ...
- 通过Metricbeat实现外部对Elastic Stack的监控
对于Elastic Stack监视的所有用户,建议使用外部数据收集. 概括一下: 关闭Elastic Stack自带的监控功能,然后使用metricbeat收集Elastic Stack数据传输到另外 ...
- k8s上安装elasticsearch集群
官方文档地址:https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html yaml文件地址:https://dow ...
- 安装 Ubuntu 教程
1.选择中文安装 2.****到了如下界面,我们点击继续: 3.然后点击,现在安装: 4.****到了这界面,点击继续: 5.如下,输入你的位置,随便输入就好: 6.****然后选择汉语,点击继续: ...
- 我的Vue之旅、05 导航栏、登录、注册 (Mobile)
第一期 · 使用 Vue 3.1 + TypeScript + Router + Tailwind.css 构建手机底部导航栏.仿B站的登录.注册页面. 代码仓库 alicepolice/Vue-05 ...
- Linux shell猜数游戏
题目:猜随机数随机1-100中的一个数字,要求用户猜数字,猜中则退出脚本并告知用户猜测次 数和随机数字,否则要求用户继续猜,并告知当前猜的数字和随机数的关系. #!/bin/bash #猜数游戏 Ra ...
- PyCharm安装PyQt5及其工具(Qt Designer、PyUIC、PyRcc)详细教程
摘要:Qt是常用的用户界面设计工具,而在Python中则使用PyQt这一工具包,它是Python编程语言和Qt库的成功融合.这篇博文通过图文详细介绍在PyCharm中如何完整优雅地安装配置PyQt5的 ...
- HDU1423 Greatest Common Increasing Subsequence (DP优化)
LIS和LCS的结合. 容易写出方程,复杂度是nm2,但我们可以去掉一层没有必要的枚举,用一个变量val记录前一阶段的最优解,这样优化成nm. 1<=k<j,j增加1,k的上界也增加1,就 ...
- this硬绑定
一.this显示绑定 this显示绑定,顾名思义,它有别于this的隐式绑定,而隐式绑定必须要求一个对象内部包含一个指向某个函数的属性(或者某个对象或者上下文包含一个函数调用位置),并通过这个属性间接 ...
- VS中git概念解析与深度使用
基础概念 四个区 工作区(Working Area) 暂存区(Stage) 本地仓库(Local Repository) 远程仓库(Remote Repository) 五种状态 未修改(Origin ...