繁体   English   中英

在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个对象。 我希望每个数组都有一个单独的计数器,以便正确填充它们。 现在的工作方式:

CombineArray首先填充一种类型的所有内容(即首先填充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内部,对cellForItem进行切换

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM