博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
优雅的使用UITableView(Swift 中)
阅读量:6968 次
发布时间:2019-06-27

本文共 3688 字,大约阅读时间需要 12 分钟。

在中,已经给大家分享了怎么使用UITableView,优雅的构建一个页面。

在这一节,主要和大家聊一聊这两点:

  1. 怎么把的思路搬到Swift
  2. 泛型Any的区别
  3. 在Swift中优雅的使用UITableView构建List页面

怎么把的思路搬到Swift

再回忆一下这张图

其中关键的点其实就是Row,如果我们把Row做好了,其实大功基本告成。

看看成果:

Swift版的是不是更优雅了些?

Row的实现

struct NoneItem {}protocol Updatable: class {        associatedtype ViewData        func update(viewData: ViewData)}extension Updatable {    func update(viewData: NoneItem) {}}protocol RowType {        var tag: RowTag { get }    var reuseIdentifier: String { get }    var cellClass: AnyClass { get }    func update(cell: UITableViewCell)    func cell
() -> C func cellItem
() -> M}class Row
where Cell: Updatable, Cell: UITableViewCell { let tag: RowTag let viewData: Cell.ViewData let reuseIdentifier = "\(Cell.classForCoder())" let cellClass: AnyClass = Cell.self init(viewData: Cell.ViewData, tag: RowTag = .none) { self.viewData = viewData self.tag = tag } func cell
() -> C { guard let cell = _cell as? C else { fatalError("cell 类型错误") } return cell } func cellItem
() -> M { guard let cellItem = viewData as? M else { fatalError("cellItem 类型错误") } return cellItem } private var _cell: Cell? func update(cell: UITableViewCell) { if let cell = cell as? Cell { self._cell = cell cell.update(viewData: viewData) } }}extension Row: RowType {}public class RowTags { fileprivate init() {}}public class RowTag: RowTags { public let _key: String public init(_ key: String) { self._key = key super.init() }}extension RowTag: Hashable { public static func ==(lhs: RowTag, rhs: RowTag) -> Bool { return lhs.hashValue == rhs.hashValue } public var hashValue: Int { return _key.hashValue }}extension RowTags { static let none = RowTag("")}复制代码

以上代码,对比OC实现主要有三点不同:

  • CellClass从参数变为泛型
  • RowType的存在
  • RowTags(主要用来取Row,代替IndexPath)

不知道你对RowType这个协议的存在是否感到疑惑,假如没有它行不行?

如果没有RowType这个协议,这两个row应该放在什么类型的数组里呢?

你打算用Any?那你的代码里肯定会出现一堆as? 的代码,显然与我们谈到的优雅背道而驰。

其实RowType的存在就是这些元素的抽象,让我们知道这些元素的共同属性。

是不是典型的面相协议编程?


泛型Any的区别

如果没有怎么接触过Swift的同学,或者不太了解泛型的同学,看到上面的语法,肯定是一脸的懵逼。

在这里简单给不太了解的同学普及一下。

泛型,泛型,从字面理解就是广泛的类型嘛,就是各种姿势都满足,但是他和Any有什么不同呢?

我们先来看这么一个需求,我想写一个max函数,他要使用各种类型,如果没有接触过泛型的同学写出来的函数应该是这样(请只看方法定义)

func anyMax(_ x: Any, _ y: Any) -> Any {    ....}复制代码

如果对于OC那样指针操作的语言这似乎没有问题,但是这对于Swift这样的强类型语言就很有问题了。

为什么?

假如我比较两个Int类型的数字,返回的是Any,这显然不是我想要的

let n = 1let m = 2// result 的类型会为Anylet result = anyMax(n, m)复制代码

再看泛型版本

func genericMax
(_ x: T, _ y: T) -> T { ....}复制代码
let n = 1let m = 2// result 的类型会为Intlet result = genericMax(n, m)复制代码

因为Swift有类型推断,所以我们在输入值比较时就知道了我们的result类型为Int

那么我们可以总结出泛型Any的最大区别就是:

  • 泛型

    • 输入与输出结果类型一致
    • 延迟类型的确定
  • Any会造成类型丢失

Swiftmax函数的实现

where关键字表示约束条件,T必须为遵循了协议Comparable的类型


在Swift中优雅的使用UITableView构建List页面

再看一遍这张图

这有三组样式的UITableView

其实ListDetail维护的东西是一样的,就是那个RowContainer

核心代码

尾巴

在此和Swift的优雅使用UITabelView都已经和大家介绍完毕了。

下一节会和大家分享一下在我开发中,对Detail界面的运用和List界面的运用,以及怎么用泛型去对Detail模型和List模型的解析。

在上一节中,有很多同学给我推荐了一些表单的库,其实我自己也知道有很多优秀的表单库,列如、等等。

那么,我为什么还要自己造轮子?

两个主要的原因:

  • 那些库都太
  • 都只支持Detail,List界面没有办法兼容

其实我也只是站在了的肩上而已


在上一节中看到评论中主要有两个问题:

  • 我用了响应链的传值方式,怎么传递参数?
func buttonAction(_ sender: UIButton) {        (self.viewController as? ButtonCellActionable)?.buttonAction(sender, cell: self)    }复制代码
  • 在执行懒加载UIbutton时,self.viewController为nil,为什么事件还能相应?

其实为nil,在我开发时,我是知道的,但我错误的理解为,系统会在运行时再去拿那个target。

为nil的原因其实是button还没有添加在superView上,响应链还找不到他的UIViewContoller。

那么既然,target没有被系统持有,那么,为什么事件还能相应?

这就是UIKit中的定义,就是target为nil的时候,会走 ,而我之前的实现,又恰好在VC中实现了,所以方法会被调用。

关于addTarget这个方法的更多事情,请看

表单库:

转载地址:http://anbsl.baihongyu.com/

你可能感兴趣的文章
nginx前端负载,后端apache获取真实IP设置
查看>>
关于Repository、Autofac、DbContext简单例子
查看>>
CF1155E Guess the Root
查看>>
SSM框架的jar使用操作
查看>>
最近用到mysql和mybatis结合常用的知识点坐下整理
查看>>
redis入侵
查看>>
ArcGIS Server发布服务,报错001270
查看>>
连续子数组的最大和
查看>>
windows7下cmd命令窗口没有滚动条的解救方法
查看>>
查看oracle数据库的连接数以及用户
查看>>
某公司git代码管理,到如何上线
查看>>
ubuntu 16.04安装mips交叉编译
查看>>
MyEclipse查看Struts2源码及Javadoc文档
查看>>
C语言基础学习day03
查看>>
js代码规范
查看>>
Algs4-2.4.24链接实现优先队列
查看>>
spring mvc 程序
查看>>
20条Linux命令面试问答
查看>>
Jmeter做并发测试(设置集合点)
查看>>
001/Nginx高可用模式下的负载均衡与动静分离(笔记)
查看>>