在 cellforitem 中显示两种不同类型的单元格 swift
displaying two different types of cells in cellforitem swift
我有两个数组,一个包含字符串,一个包含自定义对象。
我分别创建了两个不同的单元格。我已将两个数组的内容添加到第三个通用数组 Any 中。我在 cellForItem.
中使用第三个数组 (combinedArray)
var customObjectArray: [customObject] = []
var stringArray = [String]()
var combinedArray = [Any]()
if combinedArray[indexPath.row] is CustomObject {
cell1.LabelName.text = customObjectArray[indexPath.row].caption
cell1.iconView.image = customObjectArray[indexPath.row].icon
return cell1
} else {
let stringName = stringArray[indexPath.row]
cell2.LabelName.setTitle(stringName for: UIControlState())
return cell2
}
假设 customObjectArray 有 13 个对象,stringObjectArray 有 17 个对象。我希望每个数组都有一个单独的计数器,以便正确填充它们。它现在的工作方式:
combinedArray 首先填充所有一种类型(即首先填充 13 个 customObjectArray),然后是第二个类型(即 17 个 stringObjects)。组合数组的顺序不一定很重要,因为我可能会在到达 cellforitem 之前的某个时候随机播放。因此,当 cellforItem 遍历前 13 个对象时,indexpath.row = 14,并且当它到达第二类对象时,它会跳过前 13 个对象并显示 stringObject 的第 14 个元素(很明显)。
我不知道如何从第二个数组的开头而不是 indexPath.row 的当前位置开始。
我可能完全偏离了这里的基础,可能应该使用两个部分或类似性质的东西,但我对 iOS 开发人员来说还比较陌生,因此欢迎任何指导。
始终只使用一个数组,其类型比 Any
更具体
例如,创建一个包含两种类型共有的所有属性和函数的协议
protocol CommonType {
var labelName : String { get }
// var ...
// func
}
并使类型采用协议。
然后声明具有该类型的单个数组,以便能够添加两种静态类型
var commonArray = [CommonType]()
在cellForItem
中通过条件向下转换类型确定单元格类型
let common = commonArray[indexPath.row]
if common is CustomObject {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomObject", for: indexPath) as! CustomObjectCell
cell.LabelName.text = common.labelName
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "Other", for: indexPath) as! OtherCell
cell.LabelName.text = common.labelName
return cell
}
indexPath
数学很麻烦而且容易出错。
另一种选择是将不同的数据类型包含在一个枚举中,然后将所有数据以您想要的任何顺序添加到组合数组中。
enum DataHolder {
case stringType(String)
case customType(CustomObject)
}
var combinedArray: [DataHolder]
这为您提供了单一的数据类型和区分单元格类型的方法。
在 cellForItem
内部对 combinedArray
执行切换
switch combinedArray[indexPath.row] {
case .stringType(let stringValue):
let cell = tableView.dequeueReusableCell(withIdentifier: "StringCell", for: indexPath) as! StringObjectCell
cell.labelName.text = stringValue
case .customType(let customData):
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomObjectCell
cell.labelName.text = customData.caption
cell.iconView.image = customData.icon
如果您想在 UITableView
中显示 2 种不同类型的数据,您可以简单地创建一个包装 enum
,其案例将代表该类型。根据情况,您将始终知道如何配置单元。
示例:
假设您需要在 UITableView
中显示 Facebook 帖子,并且有 3 种类型的帖子:文本、图片和视频。您的 enum
想要这样:
enum Post {
case text(String)
case image(URL)
case video(URL)
}
很简单吧?
您需要为每种类型的数据创建 UITableViewCell
个子类(或者单个并正确配置它,但出于多种原因我建议分开使用)。
现在您需要做的就是保留 Post
的数组并在您的 UITableViewDataSource
中构建您需要的单元格。
let post = self.posts[indexPath].row
switch post {
case .text(let text):
let cell = // dequeue proper cell for text
// configure the cell
cell.someLabel.text = text
return cell
case .image(let url):
let cell = // dequeue proper cell for image
// configure the cell
cell.loadImage(url)
return cell
case .video(let url):
let cell = // dequeue proper cell for video
// configure the cell
cell.videoView.contentURL = url
return cell
}
我有两个数组,一个包含字符串,一个包含自定义对象。
我分别创建了两个不同的单元格。我已将两个数组的内容添加到第三个通用数组 Any 中。我在 cellForItem.
中使用第三个数组 (combinedArray)var customObjectArray: [customObject] = []
var stringArray = [String]()
var combinedArray = [Any]()
if combinedArray[indexPath.row] is CustomObject {
cell1.LabelName.text = customObjectArray[indexPath.row].caption
cell1.iconView.image = customObjectArray[indexPath.row].icon
return cell1
} else {
let stringName = stringArray[indexPath.row]
cell2.LabelName.setTitle(stringName for: UIControlState())
return cell2
}
假设 customObjectArray 有 13 个对象,stringObjectArray 有 17 个对象。我希望每个数组都有一个单独的计数器,以便正确填充它们。它现在的工作方式:
combinedArray 首先填充所有一种类型(即首先填充 13 个 customObjectArray),然后是第二个类型(即 17 个 stringObjects)。组合数组的顺序不一定很重要,因为我可能会在到达 cellforitem 之前的某个时候随机播放。因此,当 cellforItem 遍历前 13 个对象时,indexpath.row = 14,并且当它到达第二类对象时,它会跳过前 13 个对象并显示 stringObject 的第 14 个元素(很明显)。
我不知道如何从第二个数组的开头而不是 indexPath.row 的当前位置开始。
我可能完全偏离了这里的基础,可能应该使用两个部分或类似性质的东西,但我对 iOS 开发人员来说还比较陌生,因此欢迎任何指导。
始终只使用一个数组,其类型比 Any
例如,创建一个包含两种类型共有的所有属性和函数的协议
protocol CommonType {
var labelName : String { get }
// var ...
// func
}
并使类型采用协议。
然后声明具有该类型的单个数组,以便能够添加两种静态类型
var commonArray = [CommonType]()
在cellForItem
中通过条件向下转换类型确定单元格类型
let common = commonArray[indexPath.row]
if common is CustomObject {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomObject", for: indexPath) as! CustomObjectCell
cell.LabelName.text = common.labelName
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "Other", for: indexPath) as! OtherCell
cell.LabelName.text = common.labelName
return cell
}
indexPath
数学很麻烦而且容易出错。
另一种选择是将不同的数据类型包含在一个枚举中,然后将所有数据以您想要的任何顺序添加到组合数组中。
enum DataHolder {
case stringType(String)
case customType(CustomObject)
}
var combinedArray: [DataHolder]
这为您提供了单一的数据类型和区分单元格类型的方法。
在 cellForItem
内部对 combinedArray
switch combinedArray[indexPath.row] {
case .stringType(let stringValue):
let cell = tableView.dequeueReusableCell(withIdentifier: "StringCell", for: indexPath) as! StringObjectCell
cell.labelName.text = stringValue
case .customType(let customData):
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomObjectCell
cell.labelName.text = customData.caption
cell.iconView.image = customData.icon
如果您想在 UITableView
中显示 2 种不同类型的数据,您可以简单地创建一个包装 enum
,其案例将代表该类型。根据情况,您将始终知道如何配置单元。
示例:
假设您需要在 UITableView
中显示 Facebook 帖子,并且有 3 种类型的帖子:文本、图片和视频。您的 enum
想要这样:
enum Post {
case text(String)
case image(URL)
case video(URL)
}
很简单吧?
您需要为每种类型的数据创建 UITableViewCell
个子类(或者单个并正确配置它,但出于多种原因我建议分开使用)。
现在您需要做的就是保留 Post
的数组并在您的 UITableViewDataSource
中构建您需要的单元格。
let post = self.posts[indexPath].row
switch post {
case .text(let text):
let cell = // dequeue proper cell for text
// configure the cell
cell.someLabel.text = text
return cell
case .image(let url):
let cell = // dequeue proper cell for image
// configure the cell
cell.loadImage(url)
return cell
case .video(let url):
let cell = // dequeue proper cell for video
// configure the cell
cell.videoView.contentURL = url
return cell
}