自定义tableViewCell

Posted

技术标签:

【中文标题】自定义tableViewCell【英文标题】:Custom tableViewCell 【发布时间】:2016-11-29 14:09:40 【问题描述】:

我是 ios 开发新手,正在尝试创建自定义 tableViewCells,但遇到了问题。我的 tableViewCell 和一个数组有 3 个部分。当我尝试为 UITableView, cellForRowAt 的单元格分配值时,它从每个部分的顶部开始数组。 这是我的代码:

import Foundation
import UIKit

struct cellData 

let cell : Int!
let text : String!


class SettingsTableViewCell : UITableViewController

 var arrayOfCellData = [cellData]()

override func viewDidLoad() 

    arrayOfCellData = [cellData(cell : 1, text : "تغییر رنگ دکمه تنظیمات"),
                       cellData(cell : 2, text : "تغییر تصویر پشت زمینه"),
                       cellData(cell : 1, text : "تغییر رنگ قلم"),
                       cellData(cell : 2, text : "اعلانات"),
                       cellData(cell : 2, text : "صداها"),
                       cellData(cell : 2, text : "زبان"),
                       cellData(cell : 2, text : "بازگشت به حالت پیش فرض"),
                       cellData(cell : 2, text : "سوالات متداول")]




override func numberOfSections(in tableView: UITableView) -> Int 
    return 3


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    if section == 0
        return 3
    
    else if section == 1
         return 4
    
    else if section == 2

        return 1
    


    return arrayOfCellData.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    if arrayOfCellData[indexPath.row].cell == 1


        let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1

        cell.cellName_1.text = arrayOfCellData[indexPath.row].text

        return cell

    
    else if arrayOfCellData[indexPath.row].cell == 2

        let cell = Bundle.main.loadNibNamed("TableViewCell_Type2", owner: self, options: nil)?.first as! TableViewCell_Type2

        cell.cellName_2.text = arrayOfCellData[indexPath.row].text

        return cell


    
    else

        let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1

        cell.cellName_1.text = arrayOfCellData[indexPath.row].text

        return cell


    





override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? 



    if section == 0
        return "تنظیمات رنگ\n"
    
    else if section == 1
        return "تنظیمات سیستم\n"
    
    else if section == 2

        return "پشتیبانی\n"
    

    return ""
  

【问题讨论】:

不要使用像“Bundle.main.loadNibNamed”这样的旧编码方式,而是使用“registerNib”来帮助您创建单元格。另外,您可以发布您的问题的屏幕截图吗? cellForRowAtIndexPath 中,您只考虑索引路径的行。因此,每个部分从数组顶部显示相同的对象。此外,您可以在 Interface Builder 中设计多个自定义单元(我猜从 Xcode 6 开始),不需要额外的 nib。最后不要硬编码numberOfRows。使用嵌套数组或其他东西创建一个适当的模型以始终使用 count 属性。 不能只考虑indexPath.row,根据indexPath.sectionindexPath.row计算数组索引。然后你会从数组中得到准确的元素。 @NikhilManapure 你能帮帮我吗? int 索引 = 0; if section == 0 index = indexPath.row else if section == 1 index = indexPath.row + 3 else if section == 2 index = indexPath.row + 3 + 4 将此索引用于arrayOfCellData[索引].text 【参考方案1】:

这是一个数据源更方便的建议

为单元格类型创建一个枚举

enum CellType 
    case one, two

CellData 结构包含节的标题、单元格类型的数组和文本字符串的数组。

struct CellData 
    let title : String
    let typeArray : [CellType]
    let textArray : [String]

声明数据源数组

var arrayOfCellData = [CellData]()

viewDidLoad 中创建 3 个部分。对于textArray 项目使用西方文本,我深表歉意,因为我对从右到左的文本行为感到太困惑了)。

override func viewDidLoad() 
    super.viewDidLoad()
    let section0 = CellData(title: "تنظیمات رنگ\n", typeArray: [.one, .two, .one], textArray: ["Text 1", "Text 2", "Text 3"])
    let section1 = CellData(title: "تنظیمات سیستم\n", typeArray: [.two, .two, .two, .two], textArray: ["Text 4", "Text 5", "Text 6", "Text 7"])
    let section2 = CellData(title: "پشتیبانی\n", typeArray: [.two], textArray: ["Text 8"])

    arrayOfCellData = [section0, section1, section2]

现在数据源和委托方法更容易填充。 以下代码假定两个单元格都是在 Interface Builder 中直接设计的,具有名为 TableViewCell_Type1TableViewCell_Type2 的自定义类以及适当的标识符 Type1Type2

   override func numberOfSections(in tableView: UITableView) -> Int 
        return arrayOfCellData.count
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        let section = arrayOfCellData[section]
        return section.textArray.count
    


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        let section = arrayOfCellData[indexPath.section]
        let text = section.textArray[indexPath.row]
        let cellType = section.typeArray[indexPath.row]


        switch cellType 
        case .one:
            let cell = tableView.dequeueReusableCell(withIdentifier: "Type1", for: indexPath) as! TableViewCell_Type1
            cell.cellName_1.text = text
            return cell

        case .two:
            let cell = tableView.dequeueReusableCell(withIdentifier: "Type2", for: indexPath) as! TableViewCell_Type2
            cell.cellName_2.text = text
            return cell

        
    


    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? 

        let section = arrayOfCellData[section]
        return section.title
    

【讨论】:

你的答案是dequeueReusableCellWithIdentifier。她的没有!有没有什么办法可以在没有这样的情况下工作?! 我特意写了可重用单元的代码,因为它更容易实现。不幸的是,许多教程都建议使用更繁琐(和古老)的方式。【参考方案2】:

代替arrayOfCellData[indexPath.row],试试这个来计算数组中的正确索引:

   var idx = indexPath.row
   if indexPath.section == 1  idx += 3 
   else if indexPath.section == 2  idx += 7 

   // and then you can use:
   arrayOfCellData[idx]

【讨论】:

使用您的解决方案后,我遇到了编译器错误。它抱怨这个错误:二元运算符'=='不能应用于'section.Type'和'Int'类型的操作数 @fatemeh 当你想使用 == 时,你应该在 2 个具有相同类型的值上使用它。我不知道section.Type 是什么,但Int 显然是一个整数。因此,请确保您比较的是同一类型。您始终可以在变量上Ctrl + click 以查看其类型。法赫米丁? @fatemeh 部分是 indexPath.section。我认为这很明显。我已经编辑了代码。 @Honey 是的,当然。 fahmidam 蜂蜜:-D【参考方案3】:

我以这种方式更改了我的代码,并且成功了!

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    var offset = 0

    if indexPath.section == 0 

        offset = 0

     else if indexPath.section == 1 

        offset = 3

     else if indexPath.section == 2 

        offset = 7

    


    if arrayOfCellData[indexPath.row + offset].cell == 1 


        let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1

        cell.cellName_1.text = arrayOfCellData[indexPath.row + offset].text

        return cell

    
    else if arrayOfCellData[indexPath.row + offset].cell == 2 

        let cell = Bundle.main.loadNibNamed("TableViewCell_Type2", owner: self, options: nil)?.first as! TableViewCell_Type2

        cell.cellName_2.text = arrayOfCellData[indexPath.row + offset].text

        return cell


    
    else 

        let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1

        cell.cellName_1.text = arrayOfCellData[indexPath.row + offset].text

        return cell

        

【讨论】:

以上是关于自定义tableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

自定义UI 自定义布局

自定义UI 自定义布局

自定义UI 自定义布局

自定义 view - 自定义属性

Springboot+自定义注解+自定义AOP前置增强+自定义异常+自定义异常捕获

Android 自定义View