在app我的页面通常有一些个人信息的展示,接到需求:需要根据云控或后端接口来决定一些cell
展示与否,如图所示,譬如我的订单就是根据后端接口决定是否展示。 不展示的所对应的
tablView
所对应的section
即不存在。按一般逻辑,这种需求应该挺简单的,但是打开原先代码一看,傻眼了:这判断也太多了吧,一修改很容易崩溃啊。原先部分代码如下:
ini
func numberOfSections(in tableView: UITableView) -> Int {
var count = 3
if dataList02.count > 0 {
count += 1
}
if dataList00.count >= 0 {
count += 1
}
return count
}
func tableView(_: UITableView, numberOfRowsInSection section : Int) -> Int {
if dataList02.count > 0 {
if section == 0 {
return dataList00.count
// return dataList01.count
} else if section == 1 {
return dataList01.count
// return dataList02.count
} else if section == 2 {
return dataList02.count
// return dataList03.count
} else if section == 3 {
return dataList03.count
// return bannerList.count
}else {
return bannerList.count
}
} else {
if section == 0 {
return dataList00.count
// return dataList01.count
} else if section == 1 {
return dataList01.count
// return dataList03.count
}else if section == 2{
return dataList03.count
}
else {
return bannerList.count
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
if dataList00.count > indexPath.row {
let item = dataList00[indexPath.row]
cell.config(item: item)
}
if dataList00.count == 0 {
cell.isHidden = true
}
return cell
}else if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
if dataList01.count > indexPath.row {
var item = dataList01[indexPath.row]
if item.type == .voice {
item.rightValue = voiceName
} else if item.type == .theme {
item.rightValue = ThemeManager.shared.currentThemeName ?? "小思"
}
else if item.type == .task {
if PDAccountManager.isUserLogin() {
item.rightValue = "\(UserDefaultsManager.shared.user_energyNum)能量"
} else {
item.rightValue = ""
}
}
cell.config(item: item)
}
return cell
} else if indexPath.section == 2 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
let item = dataList02.count > 0 ? dataList02[indexPath.row] : dataList03[indexPath.row]
cell.config(item: item)
return cell
} else {
if dataList02.count > 0 {
if indexPath.section == 3 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
let item = dataList03[indexPath.row]
cell.config(item: item)
return cell
} else {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
} else {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if dataList00.count == 0 {
return section == 0 ? 0.0 : 12.0
}
return 12.0
}
func tableView(_: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if dataList02.count > 0 {
if indexPath.section == 0 {
return dataList00.count == 0 ? 0.0 : 56
} else if indexPath.section == 1 || indexPath.section == 2 || indexPath.section == 3{
return 56
} else {
return adaptHeightLargeMode(98)
}
} else {
if indexPath.section == 0 {
return dataList00.count == 0 ? 0.0 : 56
} else if indexPath.section == 1 || indexPath.section == 2 {
return 56
} else {
return adaptHeightLargeMode(98)
}
}
}
尝试着按原先开发人员的思路修改了几分钟,果然不出所料,需要判断的地方太多了,很难达到预期。思考了几分钟,就算这次按着原先思路改好了,下次再碰到这样的需求又要花时间和精力,太难维护了。决定使用二维数组对其改造,也是为了方便后续开发。按逻辑来看,这样的场景需求并不复杂,tableView
中的一组section
,该section
中有可能都显示,有可能都不显示,有可能只显示其中的一个cell
,所以使用二维数组再方便不过。说干就干,按这个思路,不到半小时,改造后的代码就出来了,简洁高效,也方便后续维护。 先定义一个二维数组private var dataAllList:[[MineCellItem]] = []
,然后只需要根据条件判断是否需要显示,显示的话添加到dataAllLis
t中,不显示则不需要添加。示意代码如下:
go
private func showListSection() {
//我的订单
if rights_cards_switch == true {
dataList01.append(MineCellItem(icon: "mine_order", title: "我的订单", style: .bottom, type: .order))
}
if dataList01.count > 0 {
dataAllList.append(dataList01)
}
}
tableView
改造后的代码如下:
swift
func numberOfSections(in tableView: UITableView) -> Int {
var listCount = dataAllList.count
if bannerList.count > 0 {
listCount += 1
}
return listCount
// var count = 3
// if dataList02.count > 0 {
// count += 1
// }
// if dataList00.count >= 0 {
// count += 1
// }
// if dataList04.count > 0 {
// count += 1
// }
// return count
}
func tableView(_: UITableView, numberOfRowsInSection section : Int) -> Int {
if dataAllList.count > 0,
section < dataAllList.count {
let list = dataAllList[section]
return list.count
}
if bannerList.count > 0,
section == dataAllList.count {
return bannerList.count
}
return 0
// if dataList02.count > 0 {
// if section == 0 {
// return dataList00.count
// // return dataList01.count
// } else if section == 1 {
// return dataList01.count
// // return dataList02.count
// } else if section == 2 {
// return dataList02.count
// // return dataList03.count
// } else {
// if dataList04.count > 0 {
// if section == 3 {
// return dataList04.count
// }else if section == 4 {
// return dataList03.count
// }else{
// return bannerList.count
// }
// } else {
// if section == 3 {
// return dataList03.count
// }else{
// return bannerList.count
// }
// }
// }
// } else {
// if section == 0 {
// return dataList00.count
// // return dataList01.count
// } else if section == 1 {
// return dataList01.count
// // return dataList03.count
// } else {
// if dataList04.count > 0 {
// if section == 2 {
// return dataList04.count
// } else if section == 3 {
// return dataList03.count
// }
// else {
// return bannerList.count
// }
// } else {
// if section == 2 {
// return dataList03.count
// }
// else {
// return bannerList.count
// }
// }
// }
// }
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == dataAllList.count,
bannerList.count > 0,
indexPath.row < bannerList.count {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
if dataAllList.count > 0,
indexPath.section < dataAllList.count {
let list = dataAllList[indexPath.section]
if list.count > 0, indexPath.row < list.count {
var item = list[indexPath.row]
if item.type == .voice {
item.rightValue = voiceName
} else if item.type == .theme {
item.rightValue = ThemeManager.shared.currentThemeName ?? "小思"
}else if item.type == .task {
if PDAccountManager.isUserLogin() {
item.rightValue = "\(UserDefaultsManager.shared.user_energyNum)能量"
} else {
item.rightValue = ""
}
}
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
cell.config(item: item)
return cell
}
}
return UITableViewCell()
/*
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
if dataList00.count > indexPath.row {
let item = dataList00[indexPath.row]
cell.config(item: item)
}
if dataList00.count == 0 {
cell.isHidden = true
}
return cell
}else if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
if dataList01.count > indexPath.row {
var item = dataList01[indexPath.row]
if item.type == .voice {
item.rightValue = voiceName
} else if item.type == .theme {
item.rightValue = ThemeManager.shared.currentThemeName ?? "小思"
}
else if item.type == .task {
if PDAccountManager.isUserLogin() {
item.rightValue = "\(UserDefaultsManager.shared.user_energyNum)能量"
} else {
item.rightValue = ""
}
}
cell.config(item: item)
}
return cell
} else if indexPath.section == 2 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
if dataList02.count > 0 {
let item = dataList02[indexPath.row]
cell.config(item: item)
}else{
if dataList04.count > 0 {
let item = dataList04[indexPath.row]
cell.config(item: item)
}else{
let item = dataList03[indexPath.row]
cell.config(item: item)
}
}
return cell
} else if indexPath.section == 3 {
if dataList02.count > 0 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
if dataList04.count > 0 {
let item = dataList04[indexPath.row]
cell.config(item: item)
}else{
let item = dataList03[indexPath.row]
cell.config(item: item)
}
return cell
} else {
if dataList04.count > 0 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
let item = dataList03[indexPath.row]
cell.config(item: item)
return cell
}else{
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
}
} else {
if dataList02.count > 0 {
if dataList04.count > 0 {
if indexPath.section == 4 {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineCell.self)
let item = dataList03[indexPath.row]
cell.config(item: item)
return cell
}else{
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
}else{
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
} else {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MineBannerCell.self)
let item = bannerList[indexPath.row]
cell.config(item: item)
return cell
}
}
*/
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return UIView()
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 12.0
}
func tableView(_: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if bannerList.count > 0,
indexPath.section == dataAllList.count {
return MineBannerCell.height()
}
return 56
// if dataList02.count > 0 {
// if indexPath.section == 0 {
// return dataList00.count == 0 ? 0.0 : 56
// } else if indexPath.section == 1 || indexPath.section == 2 || indexPath.section == 3{
// return 56
// } else {
// if indexPath.section == 0 || indexPath.section == 1 || indexPath.section == 2 || indexPath.section == 3{
// return 56
// } else {
// return adaptHeightLargeMode(98)
// }
// }
// } else {
// if indexPath.section == 0 {
// return dataList00.count == 0 ? 0.0 : 56
// } else if indexPath.section == 1 || indexPath.section == 2 {
// return 56
// } else {
// return adaptHeightLargeMode(98)
// }
// }
}
改造前跟改造后的代码对比下看,原先一个方法中50-60行的代码中夹杂了大量的判断,改造后不超过10行代码,而且代码简洁清晰,易于后续维护。 后续的一点思考:开发人员还是要严谨认真一点,对自己所写的代码负责,不能为了完成开发任务就不考虑更好的方案。如果一个并不复杂的场景,使用了大量的if else
那肯定是有优化空间的。找到相对优秀的方案,对于整个app工程代码质量还是自己技术上的提升都是有好处的。