更优雅地使用Static Cell

在项目开发中,经常会用到static cell来实现一些固定的列表界面(如:个人中心等),在static cell被点击时,如何判断被点击的cell是哪一个,有什么好的办法呢?

个人中心

如上界面,在storyboard下使用static cell实现起来不过一盏茶的功夫,每个cell对应的操作都不一样,那么如何确定点击的是哪一个cell呢?

方法一. 使用indexPath

似乎没什么好说的,使用indexPath来判断某一组某一行实在是太简单,如:

 if indexPath.section ==  && indexPath.row ==  {
//我的粉丝
}
if indexPath.section == && indexPath.row == {
//关于我们
}

so easy 只需要2个判断就完成了,但这并不是什么好办法。如果经常使用static cell的同学很容易就看的出来,如果cell的行数发生了改变(如:添加cell,删除cell)又或者是cell的位置发生了改变(比如:我的粉丝我的关注调换位置)这时候就需要重新编写判断条件,显而易见这不是好办法。

方法二. 使用Tag

为了解决indexPath的不足之处,很多人都会想到使用Tag,每个cell都绑定一个Tag值,这么一来无论是cell的行数发生改变,又或是cell的位置发生改变,都不会影响到判断条件,如:

                                                  给cell设置Tag值

这时候添加新的cell只需要给新的cell绑定一个Tag,或者是cell的位置发生改变,并不会影响之前的写好的判断条件。

 guard let cell = tableView.cellForRowAtIndexPath(indexPath) else { return }
switch cell.tag {
case : print("新的好友")
case : print("新手任务")
case : print("我的关注")
case : print("我的粉丝")
// ...
default: break
}

但是,根据101,102,201...这些值无法直接体现出cell对应的内容(或操作),因此可以使用enum改进一下。如:

 //先定义一个enum
enum CellName: Int {
case NewFriends = //101:第1组,第01行
case NewTask = //102:第1组,第02行
case MyFollowing = //201:第2组,第01行
case MyFans = //...
case Feedback = //...
case AboutUs = //...
case VersionInfo = //...
}
 guard let cell = tableView.cellForRowAtIndexPath(indexPath) else { return }
guard let cellName = CellName(rawValue: cell.tag) else { return }
switch cellName {
case .NewFriends: //新朋友
case .NewTaskL: //新任务
case .MyFollowing: //我的关注
case .MyFans: //我的粉丝
case .Feedback: //意见反馈
case .AboutUs: //关于我们
case .VersionInfo: //版本信息
}

这样看起来似乎还不错,但还是稍微有点不足,如果这时候需要在新的好友新手任务中间插入一行新手礼包,这时候cell的Tag值应该设置为多少呢?当然,只要是不重复的,随便设置一个Tag=103或者Tag=999都是可以的。但是这时候看起来就会些不协调了,如:

 enum CellName: Int {
case NewFriends = //101:第1组,第01行
case NovicePacks = //999:第9组,第99行(但这竟然是第1组第2行)
case NewTask = //102:第1组,第02行(但这竟然是第3行)
case MyFollowing = //...
case MyFans = //...
case Feedback = //...
case AboutUs = //...
case VersionInfo = //...
}

这样虽然也是可以的,也并没有影响之前的判断,使用enum之后一样显得很友好,但是,如果cell的位置经常改变,产品经理脑子一热就要求添加一行新的cell,脑子一冷又要求删掉某一行cell,如此反复之后,cell的Tag就会毫无顺序可言,并不好维护。
笔者虽不是处女座,但也无法接受这样的事情。

方法三. 自定义一个标识(推荐使用,笔者最喜欢的方法)

为了解决Tag反复修改之后变得无序的问题,反正迟早会变得无序,索性一开始就不考虑顺序问题。
笔者想到的办法是,给cell扩展一个字段(叫:actionIdentifier)用于表示当前cell所代表的内容(或操作),且为了能在Storyboard中设置该值,因此加上@IBInspectable修饰,如:

 private var actionIdentifierKey: Void?

 public extension UITableViewCell {

     @IBInspectable var actionIdentifier: String {
get {
return objc_getAssociatedObject(self, &actionIdentifierKey) as? String ?? ""
}
set {
objc_setAssociatedObject(self, &actionIdentifierKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
} }

这时候就可以在storyboard中这样操作,把Action identifier值设置为enum的值,如:

                                             设置ActionIdentifier值

代码操作跟方法二几乎无异,如:

 //这里Int改成String
enum ActionIdentifier: String {
case NewFriends
case NewTask
case MyFollowing
case MyFans
case Feedback
case AboutUs
case VersionInfo
}
 guard let cell = tableView.cellForRowAtIndexPath(indexPath) else { return }
guard let action = ActionIdentifier(rawValue: cell.actionIdentifier) else { return }
switch action {
case .NewFriends:
case .NewTask:
//...
}

这时候看着就顺心多了...
注意:文章中的代码段均是临时手写的,直接copy的话,不一定能编译通过。

文/Chakery(简书作者)
原文链接:http://www.jianshu.com/p/3e5ac0e8d43e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

IOS-更优雅地使用Static Cell的更多相关文章

  1. Swift iOS tableView static cell动态计算高度

    TableView是iOS开发中经常使用的组件.有些表格由于UILabel包括的文本字数不一样,须要显示的高度也会不同,因此须要动态计算static cell的高度.我用的是static cell,注 ...

  2. [改善Java代码]集合运算时使用更优雅的方式

    在初中代数中,我们经常会求两个集合的并集.交集.差集等,在Java中也存在着此 类运算,那如何实现呢? 一提到此类集合操作,大部分的实现者都会说:对两个集合进行遍历,即可求出结果.是的,遍历可以实现并 ...

  3. Lambda表达式, 可以让我们的代码更优雅.

    在C#中, 适当地使用Lambda表达式, 可以让我们的代码更优雅. 通过lambda表达式, 我们可以很方便地创建一个delegate: 下面两个语句是等价的 Code highlighting p ...

  4. 使用Castle扩展Ibatis.Net,面向接口编程-更优雅的代码

    使用Ibatis.Net做项目半年了,甚是喜欢,感觉确实是个简单.轻巧的O/R Mapping框架,特别是将Sql配置在Xml文件中,相当于直接将Dao层抽离了出来. 本文假定读者对Ibatis.Ne ...

  5. Effective java 系列之更优雅的关闭资源-try-with-resources

    背景: 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在 ...

  6. JDK8漫谈——代码更优雅

    简介 lambda表达式,又称闭包(Closure)或称匿名方法(anonymous method).将Lambda表达式引入JAVA中的动机源于一个叫"行为参数"的模式.这种模式 ...

  7. 更优雅地关闭资源 - try-with-resource及其异常抑制

    原文:https://www.cnblogs.com/itZhy/p/7636615.html 一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在 ...

  8. C#中一种替换switch语句更优雅的写法

    今天在项目中遇到了使用switch语句判断条件,但问题是条件比较多,大概有几十个条件,满屏幕的case判断,是否有更优雅的写法替代switch语句呢? 假设有这样的一个场景:商场经常会根据情况采取不同 ...

  9. JAVA8-让代码更优雅之List排序

    先定义一个实体类 @Data @AllArgsConstructor @NoArgsConstructor public class Human { private String name; priv ...

随机推荐

  1. 数据库们~MySQL~MongoDB~Redis

    mysql基础 mysql进阶 python操作mysql MongoDB Redis

  2. scrapy框架(2)

    一.使用scrapy框架发送post请求 1.需求一:使用scrapy发送百度翻译中的ajax请求 创建一个项目,如下目录,修改settings.py文件中的 "ROBOTSTXT_OBEY ...

  3. 【Python】海贼王取名字

    #-*- coding: UTF-8 -*- #coding==utf-8 #from selenium.webdriver.support.wait import WebDriverWait fro ...

  4. python分段算利润、税收

    ''' 题目:企业发放的奖金根据利润提成. 利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%: 2 ...

  5. logger类

    日志模块logging的四大组件: logger: 志类应用程序往往通调用提供api记录志handler: 志信息处理志发送(保存)同目标域filter: 志信息进行滤formatter:志格式化 L ...

  6. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

  7. centos 目录结构 快捷键 ls命令,alias别名,so:动态库 a:静态库,环境变量PATH,Ctrl+z 暂停命令,Ctrl+a 光标到行首,Ctrl+e 光标到行尾,Ctrl+u 删除光标前所有字符 Ctrl+r 搜索命 hash命令 Ctrl+左箭头/右箭头 cd命令 第三节课

    centos 目录结构 快捷键 ls命令,alias别名,so:动态库 a:静态库,环境变量PATH,Ctrl+z 暂停命令,Ctrl+a 光标到行首,Ctrl+e 光标到行尾,Ctrl+u 删除光标 ...

  8. Spring 小知识

    1:Advice环绕通知相当于  aop:before之类的 2:Mybatis执行流程: Configuration对象时运行项目时,就直接生成了. 2.1 通过XMLBuilder 解析XML,  ...

  9. arthas使用介绍

    背景: 一次线上问题的综合排查排查,两个相同的系统的某个模块,数据量更少的系统查询更慢. 先说下整体思路: 查看系统整理负载,网络有100左右毫秒的延迟,看起来影响不大 查看正序运行整体情况,一次查询 ...

  10. CCPC-Wannafly Winter Camp Day5 (Div2, onsite)

    Replay: Dup4: 时间复杂度算不对? 一点点思路不经过验证就激动的要死? 浪费自己一个小时还浪费别人一个小时? 对1e3不敏感? 1e3 * 1e3是多少? 模拟建边跑dp不写非要写个大模拟 ...