多个自定义 UITableViewCell 互相覆盖 Swift

Multiple Custom UITableViewCell Overwriting Eachother Swift

我正在尝试创建具有多个自定义 UITableViewCell 的 table 视图。如果我只使用一个自定义单元格,则会显示正确的单元格。如果我添加我的第二个单元格,显示第二个单元格会覆盖第一个单元格并禁止交互,第二个单元格会显示第一个自定义单元格的默认数据,直到它被选中然后显示正确的单元格。

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
    }
}


}

My Account cell controllers,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

}

}

问题是,即使您没有为该行创建单元格,您也在出队 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 的工作原理很重要。

假设您在 table 中有 100 个单元格。如果您的设备(比如 iPhone)一次只能显示 10 个,那么创建和管理所有 100 个这些单元将是一种浪费。出队基于这个原则,您只需要分配尽可能多的单元格,因为您将要显示。所以每次你需要一个新的单元格(每次 cellForRowAtIndexPath 被调用)你只想出列你需要的单元格类型,如果一个单元格同时离开屏幕,你可以重用它,而不是删除它并经历(可能)创建新单元格的繁重过程。

知道了这一点,我仍然有点不清楚为什么为单个索引将两个单元格出列会破坏布局,但它显然混淆了 TableView。作为在单个 tableView 中处理多个自定义单元格时的一般经验法则,最好将 cellForRowAtIndexPath 拆分为每种类型的单元格的单独函数(如果可能,也可能拆分为不同的部分)这就说得通了)。这样你就可以在 indexPath.rowswitch 并根据行调用你自己的自定义 dequeueThisSettingsCelldequeueOtherSettingsCell,将单元格返回到 cellForRowAtIndexPath 然后 returns 它到 table 视图。这也大大缩短了 cellForRowAtIndexPath,明确了哪种 cell 为什么 row/section 出队,并将每个 cell 的设置分成不同的函数(这有助于清晰度和可读性)。