I have two Xib's in tableview, One is cell custom UITableViewCell Xib and second is UIView custom view xib (which is footerView
). On clicking date cell it shows me appointment list. (image attached for reference).
I am getting data from SQLite
and then records append to model.
footerView
. First when it load data its fine. When I move/scorll tableView or come back to same page it shows duplicate. for loop
displaying appointment list record in footerView. (in cellForRowAt)var downloadAppData: [DownloadDisplay] = []
How to avoid duplicating footer view rows in cell TableView?
deceleration:
var downloadAppData: [DownloadDisplay] = []
Model:
struct DownloadDisplay : Codable {
var date: Int64?
var appointments: [Appointment]?
var progress: Double?
var isFinished: Bool?
}
struct Appointment : Codable {
let appointmentHour : String?
let backgroundColorDark : String?
let backgroundColorLight : String?
let controlHour : String?
let date : String?
let id : Int?
let isProjectManual : Bool?
let projectDistrict : String?
let projectFirmName : String?
let projectName : String?
let projectType : String?
let subTitle : String?
let warmingType : String?
}
TableView:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return downloadAppData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DownloadEntryViewCell", for: indexPath) as! DownloadEntryViewCell
let dic = downloadAppData[indexPath.row]
let content = datasource[indexPath.row]
let appDate = Date(milliseconds: dic.date ?? 0)
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "tr_TR_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
dateFormatter.dateFormat = "dd MMMM yyyy EEEE"
let convertDate = dateFormatter.string(from: appDate)
cell.fileNameLabel.text = "\(convertDate)" + " Randevuları"
var stackHeight:CGFloat = 0.0
// footer view xib.
for i in (dic.appointments)! {
let child_view = Bundle.main.loadNibNamed("FooterView", owner: self, options: nil)?.first as! FooterView
child_view.projName.text = "\(i.projectName ?? "")" + " " + "\(i.subTitle ?? "")"
cell.stackViewFooter.addArrangedSubview(child_view)
stackHeight = stackHeight + 33.0
}
if content.expanded == false {
cell.rightView.backgroundColor = ("#556f7b").toColor()
cell.fileNameLabel.textColor = ("#eceff1").toColor()
cell.progressLabel.textColor = ("#eceff1").toColor()
cell.individualProgress.frame = CGRect(x: 0, y: 69, width: 360, height: 2)
cell.individualProgress.progress = 0
cell.individualProgress.backgroundColor = ("#cfd8dc").toColor()
}
return cell
}
Cells are reused. That means anything you do to a cell will still be in effect when that cell is reused.
In your case, you are adding (more) subviews to a stackView each time cellForRowAt
is called.
You could either:
A) edit your cell class and implement prepareForReuse()
, where you would remove any existing subviews from the stackView
override func prepareForReuse() {
self.stackViewFooter.subviews.forEach {
$0.removeFromSuperview()
}
}
or
B) remove the subviews before adding new ones in cellForRowAt
// first
cell.stackViewFooter.subviews.forEach {
$0.removeFromSuperview()
}
// then
for i in (dic.appointments)! {
...
cell.stackViewFooter.addArrangedSubview(child_view)
}