在同一个 uitableview 中显示两个不同的自定义单元格 - swift firebase
Posted
技术标签:
【中文标题】在同一个 uitableview 中显示两个不同的自定义单元格 - swift firebase【英文标题】:Show two different custom cells in same uitableview - swift firebase 【发布时间】:2016-09-19 11:12:17 【问题描述】:我目前在同一个 uitableview 上显示两种不同类型的自定义单元格时遇到问题。
到目前为止,我所管理的是接收更新单元的“更新”,称为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
,但这是不可能的,因为我不能在numberOfRowsInSection
中有两个返回值,这是一个问题,因为该数字指的是数据存储在我的 firebase 数据库中的位置。如何修改它以使其正常工作?
希望你们明白我的意思,否则请告诉我,我会尽力解释得更好:-)
【问题讨论】:
请添加cellForRowAtIndexPath
方法的其余部分,因为这在这种情况下也很重要。
请告诉我您希望以什么顺序显示两个不同的单元格?所有单元格后跟所有任务单元格?
@SamM 这就是我目前所有的cellForRowAtIndexPath
,如果我让它工作,以后还会有更多,我想在 cellTask 之前显示单元格 - 如果可能的话?
检查我的答案,它将显示所有单元格,然后显示所有单元格任务。如果您需要它们像 cell/cellTask/cell/cellTask... 告诉我,我会更新答案。
我宁愿拥有那个!那将是真棒! @萨姆
【参考方案1】:
如果您想将它们分成两个部分,@Callam 的回答非常棒。
如果您希望所有人都在一个部分中,这就是解决方案。
首先,在numberOfRowsInSection
方法中,您需要返回这两个数组计数的总和,如下所示:return (updates.count + updatesTask.count)
那么你需要像这样配置cellForRowAtIndexPath
方法:
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
这将显示所有单元格,然后显示所有单元格任务。
如果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
【讨论】:
有什么方法可以混合细胞吗?随机显示它们,而不是先显示所有更新,然后再显示所有 updateTasks? @D.Finnaupdates
数组和updatesTask
数组是否有相同数量的项目?
哦!我误解了你所说的相同数量的项目是什么意思!不,您不能确定 updates 和 updatesTask 中的项目数是否相等【参考方案2】:
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()
【讨论】:
【参考方案3】:对于每一行,您必须选择是显示一种类型的单元格还是显示另一种类型的单元格,但不能同时显示两者。您应该在 numberOfRowsInSection 中有一个标志,告诉您的方法您要加载 Cell 或 CellTask,然后返回正确的行数。
【讨论】:
【参考方案4】:您应该在您的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
【讨论】:
【参考方案5】:我不确定你想要实现什么。如果你想显示单元格的数量 updates[] 和 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
使用 if 条件,您可以选择从哪个数组中获取数据。 但请注意将数组命名为与您在此处所做的另一个常量完全相同的名称
let updateTask = updatesTask[indexPath.row]
【讨论】:
我会试试你的代码,因为我相信它真的会帮助我解决我的问题。但请告诉我,>
不应该反过来吗?喜欢这个<
?如果不是,请告诉我原因,因为我相信反过来说才有意义:-)
应用程序崩溃,因为它在展开可选值时意外发现 nil。错误在这里:if indexPath.row > updates.count
并且 indexPath.row 和 updates.count 都在打印 0
你刚刚发布了这个 sn-p。如果你想要一个完整的答案,你必须发布你的整个班级。您可能没有在课堂上初始化您要求的数组。
奇怪的是,如果我在我的代码中完全摆脱了 cellTask,我可以用一个自定义单元格显示我的提要吗?这对我没有意义。
也许你应该先阅读苹果的 UITableView 文档,以便更好地了解它是如何工作的developer.apple.com/reference/uikit/uitableview【参考方案6】:
您可以创建一个简单的视图模型,它将包含多种项目类型:
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
然后为每个部分创建一个模型项类型。例如:
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
一旦你配置了所有的部分项目,你就可以将它们保存在 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
配置章节标题也会很整洁:
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
【讨论】:
以上是关于在同一个 uitableview 中显示两个不同的自定义单元格 - swift firebase的主要内容,如果未能解决你的问题,请参考以下文章