多个自定义UITableViewCell覆盖彼此Swift

时间:2016-01-06 22:48:46

标签: ios swift tableview tableviewcell

我正在尝试使用多个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

}

}

1 个答案:

答案 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上调用自己的自定义dequeueThisSettingsCelldequeueOtherSettingsCell,具体取决于行,将单元格返回cellForRowAtIndexPath然后将其返回到tableView。这也大大缩短了cellForRowAtIndexPath,明确了什么类型的单元格为什么行/部分出列,并将每个单元格的设置分成不同的功能(这有助于清晰度和可读性)。