在同一个uitableview中显示两个不同的自定义单元格 – swift firebase

我目前有一个在同一个uitableview显示两种不同types的自定义单元格的问题。

到目前为止我pipe理的是正在接收更新单元的“更新”(称为cell 。 我只是不知道如何获得numberOfRowsInSection返回两个值,所以我的两个单元格将显示。

让我通过我的代码解释:

 override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return updates.count return updatesTask.count // I CANNOT DO THIS - what can I do instead? } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell let update = updates[indexPath.row] let updateTask = updatesTask[indexPath.row] // Example of the two different cells that need different data from firebase cell.nameLabel.text = update.addedByUser cellTask.nameLabel.text = updateTask.addedByUser 

正如你可能看到的那样, let updateTask indexPath.row试图获得一个indexPath.row但这是不可能的,因为在numberOfRowsInSection我不能有两个返回值,这是一个问题,因为这个数字指的是数据所在的地方存储在我的firebase数据库..我怎样才能修改这个工作?

希望你们明白我要去哪里,否则让我知道,我会尽力解释:-)

如果你想把他们分成两部分,卡拉姆的答案是非常好的。

如果你想全部在一个部分,这是解决scheme。

首先,在numberOfRowsInSection方法中,您需要返回这两个数组的总和,如下所示: return (updates.count + updatesTask.count)

那么你需要像这样configurationcellForRowAtIndexPath方法:

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.row < updates.count{ // Updates let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell let update = updates[indexPath.row] cell.nameLabel.text = update.addedByUser return cell } else { // UpdatesTask let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell let updateTask = updatesTask[indexPath.row-updates.count] cellTask.nameLabel.text = updateTask.addedByUser return cellTask } } 

这将显示所有cellTask​​s之后的所有单元格。


如果updates数组和updatesTask数组有相同数量的项目,并且要逐一显示它们,则可以使用以下内容:

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.row % 2 == 0 { // Updates let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell let update = updates[indexPath.row/2] cell.nameLabel.text = update.addedByUser return cell } else { // UpdatesTask let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell let updateTask = updatesTask[indexPath.row/2] cellTask.nameLabel.text = updateTask.addedByUser return cellTask } } 

对于每行你必须select,如果你想显示一种types的单元格或其他,但不是两个。 您应该在numberOfRowsInSection中有一个标志,告诉您的方法您要加载Cell或CellTask​​,然后返回正确数量的行。

您应该返回numberOfRowsInSection方法中的total number of rows 。 所以你可以返回summation你的两个数组的数量,

  return updates.count + updatesTask.count 

现在在你的cellForRowAtIndexPath方法,你可以区分你的单元格,

  let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell if indexPath.row % 2 == 1 { //your second cell - configure and return return cellTask } else { //your first cell - configured and return return cell } 
  override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 2 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch section { case 0: return updates.count case 1: return updatesTask.count default: return 0 } } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { switch indexPath.section { case 0: let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell let update = updates[indexPath.row] cell.nameLabel.text = update.addedByUser return cell case 1: let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell let updateTask = updatesTask[indexPath.row] cell.nameLabel.text = updateTask.addedByUser return cell default: return UITableViewCell() } } 

我不确定你想要达到什么目的。 如果你想显示单元格数量更新[]和updatesTask []有元素,你可以这样做

 override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return (updates.count + updatesTask.count) } 

那么你可以像这样修改你的cellForRowAtIndexPath方法:

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell if indexPath.row < updates.count{ //update let update = updates[indexPath.row] cell.nameLabel.text = update.addedByUser }else{ let updateTask = updatesTask[indexPath.row] cellTask.nameLabel.text = updateTask.addedByUser } return cell } 

与条件,你可以select你正在采取数据的数组。 但要小心的命名一个数组,就像你在这里做的另一个常量一样

 let updateTask = updatesTask[indexPath.row] 

您可以创build一个简单的视图模型,它将包含多个项目types:

 enum ViewModelItemType { case nameAndPicture case about case email case friend case attribute } protocol ViewModelItem { var type: ViewModelItemType { get } var rowCount: Int { get } var sectionTitle: String { get } } 

然后为每个部分创build一个模型项目types。 例如:

 class ViewModelNameAndPictureItem: ViewModelItem { var type: ProfileViewModelItemType { return .nameAndPicture } var sectionTitle: String { return “Main Info” } var rowCount: Int { return 1 } var pictureUrl: String var userName: String init(pictureUrl: String, userName: String) { self.pictureUrl = pictureUrl self.userName = userName } } 

一旦您configuration了所有部分项目,您可以将它们保存在ViewModel中:

 class ProfileViewModel { var items = [ViewModelItem]() } 

并添加到你的TableViewController:

 let viewModel = ViewModel() 

在这种情况下,NumberOfSections,NumberOfRows和CellForRowAt方法将变得干净和简单:

 override func numberOfSections(in tableView: UITableView) -> Int { return viewModel.items.count } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return viewModel.items[section].rowCount } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let item = viewModel.items[indexPath.section] switch item.type { // configure celll for each type } } 

configuration节标题也将非常整齐:

 override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return viewModel.items[section].sectionTitle } 

请检查我最近的这个主题的教程,这将回答你的问题的细节和例子:

https://medium.com/ios-os-x-development/ios-how-to-build-a-table-view-with-multiple-cell-types-2df91a206429