我正在尝试使用多个Custom UITableViewCells创建一个表视图。如果我只使用一个自定义单元格,则会显示正确的单元格。如果我添加第二个单元格,显示第二个单元格将覆盖第一个单元格并禁止交互,第二个单元格显示第一个自定义单元格的默认数据,直到选中它然后显示正确的单元格。
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let nib1 = UINib(nibName: "AccountCell1", bundle: nil)
tableView.registerNib(nib1, forCellReuseIdentifier: "SettingCell1")
let nib2 = UINib(nibName: "AccountCell2", bundle: nil)
tableView.registerNib(nib2, forCellReuseIdentifier: "SettingCell2")
//removing empty rows
tableView.tableFooterView = UIView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
/*let cell = tableView.dequeueReusableCellWithIdentifier( "AccountCell", forIndexPath: indexPath) as! UITableViewCell*/
let cell1 = tableView.dequeueReusableCellWithIdentifier( "SettingCell1", forIndexPath: indexPath) as! AccountCell1Controller
let cell2 = tableView.dequeueReusableCellWithIdentifier( "SettingCell2", forIndexPath: indexPath) as! AccountCell2Controller
// Configure the cell...
if(indexPath.row == 0)
{
let imageName = "Amanda.jpeg"
let image = UIImage(named: imageName)
cell1.UserImage.image = image
cell1.UserLabel.text = "@AmandaSmith"
cell1.setNeedsLayout()
return cell1
}
else
{
return cell2
}
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if(section == 0)
{
return "John Smith"
}
else if(section == 1)
{
return "Settings"
}
else if(section == 2)
{
return "About"
}
return ""
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(indexPath.row == 0)
{
return 204
}
else if(indexPath.row == 1)
{
return 61
}
else {
return 44
}
}
}
我的帐户单元控制器,2是两个带有相应操作的按钮
class AccountCell1Controller: UITableViewCell {
@IBOutlet weak var UserImage: UIImageView!
@IBOutlet weak var UserLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
let user = UserData.self
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
答案 0 :(得分:1)
问题在于,即使您没有为该行创建单元格,也会使cell1
出列。
只尝试将您实际需要的单元格取消给定indexPath.row
:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
if(indexPath.row == 0) {
let cell1 = tableView.dequeueReusableCellWithIdentifier( "SettingCell1", forIndexPath: indexPath) as! AccountCell1Controller
let imageName = "Amanda.jpeg"
let image = UIImage(named: imageName)
cell1.UserImage.image = image
cell1.UserLabel.text = "@AmandaSmith"
cell1.setNeedsLayout()
return cell1
} else {
let cell2 = tableView.dequeueReusableCellWithIdentifier( "SettingCell2", forIndexPath: indexPath) as! AccountCell2Controller
return cell2
}
}
要理解为什么出列的数据会破坏事物,了解TableView的工作原理非常重要。
假设您在表格中有100个单元格。如果您的设备(比如iPhone)一次只能显示10个,那么创建和管理所有100个单元格将是浪费。基于此原则的队列出奇,您只需要分配尽可能多的单元格,就像您要显示的那样。因此,每次需要一个新单元格(每次调用cellForRowAtIndexPath
时),您只想将所需的单元格类型出列,如果单元格同时离开屏幕,则可以重复使用它,而不是删除它并经历(可能)繁重的创建新单元格的过程。
知道这一点,我仍然有点朦胧为什么为单个索引出列两个单元格会破坏布局,但它显然混淆了TableView。作为在单个tableView中处理多个自定义单元格时的一般经验法则,最好将cellForRowAtIndexPath
拆分为每种类型单元格的单独函数(如果有意义,也可能分为不同的部分)。这样您就可以在switch
indexPath.row
上调用自己的自定义dequeueThisSettingsCell
或dequeueOtherSettingsCell
,具体取决于行,将单元格返回cellForRowAtIndexPath
然后将其返回到tableView。这也大大缩短了cellForRowAtIndexPath
,明确了什么类型的单元格为什么行/部分出列,并将每个单元格的设置分成不同的功能(这有助于清晰度和可读性)。