我试图改进一些工作但丑陋代码。
我的应用程序有五个TableView,每个都显示不同类型的数据(具有不同的单元格布局)。因为数据类型是相似的并且需要许多类似的方法(用于下载,编码等),所以我设置了一个TableViewController:UITableViewController类作为五个TableViewController子类的超类。在这个超类中,我有标准的" cellForRowAt"方法,但它臃肿和重复。我想简化它。
我的问题(我认为)是倍数"让cell ="语句,根据数据类型转换为不同类型的TableViewCell。例如,我的DataType.SCHEDULES数据类型需要获得一个SchedulesTableViewCell,其reuseID为" SchedulesCell"。我无法使它们成为同一个TableViewCell类,因为它们每个都有自己的IBOutlet视图。
使事情变得更加丑陋,每个tableView都有两个单元格原型,我需要能够为每种数据类型生成一个ARTICLE单元格和一个DETAIL单元格。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// get the article and row type
let article = getArticleFor(indexPath: indexPath)
let cellType = getCellTypeFor(indexPath: indexPath)
// create either an ARTICLE row or a DETAIL row.
// (simplified for SO posting. Each "case" is actually
// 5-6 lines of nearly identical code)
switch cellType {
// for the ARTICLE cell prototype
case CellType.ARTICLE:
// get the right table cell matching the datatype
switch self.datatype {
case DataType.SCHEDULES:
let cell = tableView.dequeueReusableCell(withIdentifier: "SchedulesCell") as! SchedulesTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.LUNCH:
let cell = tableView.dequeueReusableCell(withIdentifier: "LunchCell") as! LunchTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.EVENTS:
let cell = tableView.dequeueReusableCell(withIdentifier: "EventsCell") as! EventsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.DAILY_ANN:
let cell = tableView.dequeueReusableCell(withIdentifier: "DailyannCell") as! DailyannTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.NEWS:
let cell = tableView.dequeueReusableCell(withIdentifier: "NewsCell") as! NewsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
}
// or for the DETAIL cell prototype
case CellType.DETAIL:
// get the right table cell matching the datatype
switch self.datatype {
case DataType.SCHEDULES:
let cell = tableView.dequeueReusableCell(withIdentifier: "SchedulesDetailsCell") as! ScheduleDetailTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.LUNCH:
let cell = tableView.dequeueReusableCell(withIdentifier: "LunchDetailsCell") as! LunchDetailsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.EVENTS:
let cell = tableView.dequeueReusableCell(withIdentifier: "EventsDetailsCell") as! EventsDetailTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.DAILY_ANN:
let cell = tableView.dequeueReusableCell(withIdentifier: "DailyannDetailCell") as! DailyannDetailsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.NEWS:
let cell = tableView.dequeueReusableCell(withIdentifier: "NewsDetailCell") as! NewsDetailTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
}
}
}
我最初拥有每个"让cell ="子类中的情况'拥有" cellForRowAt"方法,但我在每个子类中重复非常相似的代码,这似乎很愚蠢。另一方面,上面的代码将重复移动到一个单独的类中,但没有删除重复,所以它仍然是愚蠢的,但在另一个地方。
我觉得如果我可以制作课程词典,就像这样......
let tableCellClasses = [DataType.SCHEDULES : ScheduleTableViewCell,
DataType.LUNCH : LunchTableViewCell
etc.
...然后我可以让我的"让细胞="陈述更通用,比如......
let cell = tableView.dequeueReusableCell(withIdentifier: identifier[dataType]) as! tableCellClasses[dataType]
但似乎找不到让它发挥作用的方法。
正如我所说,它有效,但它很难看。我在一所高中工作,所以我希望学生能够查看回购,看看干净,结构良好的代码 - 所以我的拍摄效果不仅仅是"它有效。&#34 ;
有什么建议吗?
答案 0 :(得分:1)
你可以使用Swift的meta类型,但是看看你的代码,你所有的单元子类共享相同的方法:
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
为什么不:
有一个基类,所有自定义单元类继承,实现上面的接口(出列单元格后使用的三种方法,可能会在每个具体的子类上重写),所以出列一次并强制转换为基类型(我相信对于每个子类,将执行方法的正确实现。转换只是为了使编译器满意:UITableViewCell
没有那些方法)。
在数据类型上设置一个switch子句,为您提供特定的单元格标识符
将每个原型单元设置为storyobard上的特定类,并分配特定标识符。
有意义吗?
现在,看看你的代码,看起来你真的不需要不同的子类。拥有相同 UITableViewCell
子类的几种不同原型是完全可以的,每种子类都有不同的子视图布局和不同的重用标识符,只要它们都可以使用相同的数字和类型子视图和其他自定义属性/方法。
答案 1 :(得分:-1)
没有办法做你的假设。您必须逐个为您的需要逐个编译类。或者您可以使用基类来实现您需要的所有方法,并通过数据类型调用它们。