假如有一个账号信息页面,布局如下。。你该如何设置你的数据源呢,以及该如何处理你的tableview的点击代理呢???
![](https://img.haomeiwen.com/i1421310/4f33cc0d383af2ab.png)
以往,也就是大部分的数据源问题我就不列出来了。。。
我写下大部分人的点击代理的写法
func didSelectRowAtIndexPath(indexPath: NSIndexPath, atContol control: UIViewController) {
switch indexPath.section {
case 0:
switch indexPath.row {
case 0:
print("头像")
case 1:
print("用户名")
case 2:
print("ID")
case 3:
print("等级")
case 4:
print("vip")
default:
print("密码")
}
case 1:
print("身份证")
case 2:
print("银行")
case 3:
print("qq")
case 4:
print("淘宝")
default:
print("京东")
}
}
上面这个写法很正确。。。。没有什么可以说的。但是你就不觉得代码很难看吗???
而且你还要去看看数据源中对应的是哪个???比如,你还得看看等级是在那个section,哪个row
假如说第2个分区有3个row呢,第三个分区有5个row呢。。。。那你这个方法里全是switch case 了,嵌套在嵌套,累不累
你累不累啊。。。你就不想换个其它思路,其它写法???
开工~~~啥都不说了,上代码
首先定义一个枚举
/**
账号信息页面枚举
- Icon: 头像
- Name: 用户名
- ID: ID
- Level: 用户等级
- Vip: 我的Vip
- Password: 用户密码
- Card: 身份证信息
- Bank: 银行卡
- QQ: QQ号
- TB: 淘宝
- JD: 京东
*/
enum AccountMenu: Int {
case Icon = 0, Name, ID, Level, Vip, Password, Card, Bank, QQ, TB, JD
}
//这里我设置的枚举类型是Int,当然你也可以根据需求设置其它类型
Swift
枚举中支持以下四种关联值类型:
整型(Integer)
浮点数(Float Point)
字符串(String)
布尔类型(Boolean)
然后为这个枚举写个扩展
extension AccountMenu {
/// 信息页面菜单的信息(标题----图像----下一个控制器)
var menuInfo: (title: String, icon: UIImage?, nextControl: UIViewController?) {
get {
switch self {
case .Icon:
return ("头像", ACCOUNT_ICON, nil)
case .Name:
return ("用户名", ACCOUNT_NAME, nil)
case .ID:
return ("ID", ACCOUNT_ID, nil)
case .Level:
return ("用户等级", ACCOUNT_LEVLE, nil)
case .Vip:
return ("我的vip", ACCOUNT_VIP, nil)
case .Password:
return ("用户密码", ACCOUNT_PWD, nil)
case .Card:
return ("身份证信息", ACCOUNT_CARD, nil)
case .Bank:
return ("银行卡", ACCOUNT_BANK, nil)
case .QQ:
return ("QQ号", ACCOUNT_QQ, UIViewController())
case .TB:
return ("淘宝", ACCOUNT_TB, nil)
case .JD:
return ("京东", ACCOUNT_JD, nil)
}
}
set {
}
}
}
尽管增加一个存储属性到枚举中不被允许,但你依然能够创建计算属性。当然,计算属性的内容都是建立在枚举值下或者枚举关联值得到的。
然后在viewModel里面设置数据源
struct AccountViewModel {
/// 数据源---[key: [(数组(AccountMenu))]]
private let dataSource: [String: [AccountMenu]] = ["0": [.Icon, .Name, .ID, .Level, .Vip, .Password], "1": [.Card], "2": [.Bank], "3": [.QQ], "4": [.TB], "5": [.JD]]
}
我敢保证这个数据源,比绝大部分人的数据源要好看些。。。。。
后面的就是处理了。。。。我就直接上代码了
extension AccountViewModel {
func numberOfSections() -> Int {
return dataSource.count
}
func numberOfRowsInSection(section: Int) -> Int {
guard let count = dataSource["\(section)"]?.count else {
return 0
}
return count
}
func cellForRowAtIndexPath(indexPath: NSIndexPath, atTableView tableView: UITableView) -> UITableViewCell {
let identifier = "accountRootCell"
var cell = tableView.dequeueReusableCellWithIdentifier(identifier)
if cell == nil {
cell = UITableViewCell(style: .Value1, reuseIdentifier: identifier)
}
cell?.separatorInset = UIEdgeInsetsZero
if let sectionArr = dataSource["\(indexPath.section)"] {
cell?.imageView?.image = sectionArr[indexPath.row].menuInfo.icon
cell?.textLabel?.text = sectionArr[indexPath.row].menuInfo.title
}
return cell!
}
func didSelectRowAtIndexPath(indexPath: NSIndexPath, atContol control: UIViewController) {
guard let sectionArr = dataSource["\(indexPath.section)"],
let nextVC = sectionArr[indexPath.row].menuInfo.nextControl else {
return
}
nextVC.hidesBottomBarWhenPushed = true
control.navigationController?.pushViewController(nextVC, animated: true)
}
}
当然如果你要处理点击事件。。你也可以按照下面这个写法
func didSelectRowAtIndexPath(indexPath: NSIndexPath, atContol control: UIViewController) {
guard let sectionArr = dataSource["\(indexPath.section)"] else {
return
}
let type = sectionArr[indexPath.row]
print(type)
//如果你想做其他动作---可以直接按照下面这个来了
switch type {
case .Icon:
print("icon")
case .Name:
print("name")
case .ID:
print("id")
case .Level:
print("level")
case .Vip:
print("vip")
case .Password:
print("pwd")
case .Card:
print("card")
case .Bank:
print("bank")
case .QQ:
print("qq")
case .TB:
print("tb")
case .JD:
print("jd")
}
}
在这里。。。你就不用按照indexPath来区分了,而是直接来按照枚举类型来做的。。。。代码是比最上面那个方法多,但是你不觉得这代码写的很好看吗????
当然swift的枚举还有其它更NB的用法。。这里我暂时还没有搞明白,等过段时间再写swift枚举的其它用法吧
网友评论