這是一個(gè)在日常開發(fā)中經(jīng)常會(huì)遇到的問題基括。先來看看產(chǎn)生問題的代碼:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell? = nil
cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
let segment = UISegmentedControl(items: ["value1", "value2"])
segment.frame = CGRect.init(x: 8.0, y: 9.5, width: kScreenWidth - 16.0, height: 25.0)
segment.selectedSegmentIndex = tempIndex
segment.addTarget(self, action: #selector(segmentValueDidchanged(sender:)), for: .valueChanged)
cell!.contentView.addSubview(segment)
return cell!
}
@objc func segmentValueDidchanged(sender: UISegmentedControl) {
tempIndex = sender.selectedSegmentIndex
tableView.reloadData()
}
我的目標(biāo)是想在 cell 上添加一個(gè) segmentedControl煤墙,segmentedControl 的選定值由一個(gè)外部變量 tempIndex 來指定铸豁。同時(shí),在其點(diǎn)擊事件中重載 tableView跛梗。但是運(yùn)行上述代碼弊琴,當(dāng)切換 segmentedControl 時(shí),你會(huì)發(fā)現(xiàn) cell 上的 view 被遮擋了驱闷。原因是因采用了 tableView 的復(fù)用耻台,從隊(duì)列中拿過來的復(fù)用 cell 上已經(jīng)有添加的 segmentedControl,在這基礎(chǔ)上會(huì)再創(chuàng)建一個(gè) segmentedControl 添加上去空另。
那該如何解決這個(gè)問題呢盆耽?
方法一
在 cell 的 contentView 添加子視圖前先刪掉其上所有的子視圖:
_ = cell!.contentView.subviews.map { $0.removeFromSuperview() }
// 添加子視圖的代碼
當(dāng)子視圖的個(gè)數(shù)很多時(shí),從性能角度講不推薦該方法扼菠。
方法二
自定義 UITableViewCell:
class MyCell: UITableViewCell {
var segment: UISegmentedControl!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
segment = UISegmentedControl(items: ["value1", "value2"])
segment.frame = CGRect.init(x: 8.0, y: 9.5, width: kScreenWidth - 16.0, height: 25.0)
self.contentView.addSubview(segment)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: MyCell? = nil
cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? MyCell
if cell == nil {
cell = MyCell(style: .default, reuseIdentifier: "cell")
}
cell!.segment.selectedSegmentIndex = tempIndex
cell!.segment.addTarget(self, action: #selector(segmentValueDidchanged(sender:)), for: .valueChanged)
return cell!
}
當(dāng)需要添加很多子視圖時(shí)摄杂,推薦使用該方法。
方法三
設(shè)置子視圖的 tag 值循榆,并通過 viewWithTag 方法獲取子視圖析恢。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell? = nil
cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
if let segment = cell!.contentView.viewWithTag(888) as? UISegmentedControl {
// 已經(jīng)添加了該子視圖
segment.selectedSegmentIndex = tempIndex
} else {
let segment = UISegmentedControl(items: ["value1", "value2"])
segment.frame = CGRect.init(x: 8.0, y: 9.5, width: kScreenWidth - 16.0, height: 25.0)
segment.selectedSegmentIndex = tempIndex
segment.tag = 888
segment.addTarget(self, action: #selector(segmentValueDidchanged(sender:)), for: .valueChanged)
cell!.contentView.addSubview(segment)
}
return cell!
}
我個(gè)人推薦這種方法。