自定义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.section
和indexPath.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_Type1
和 TableViewCell_Type2
的自定义类以及适当的标识符 Type1
和 Type2
:
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的主要内容,如果未能解决你的问题,请参考以下文章