JTAppleCalendarView:无法清除 prepareForReuse 中的 DateCell
JTAppleCalendarView: Unable to clear DateCell in prepareForReuse
I am attempting to clear the DateCell in prepareForReuse
but my implementation doesn't seem to work when a DateCell
containing Activities
were selected.
我有以下设置:
- 仅 4 月 3 日和 4 月 4 日的虚拟数据
- 当有
activities
时,则在日期下方渲染一个stackView
包含点。
我的实现在以下情况下工作正常,即正确清理和重复使用单元格:
- 未选择
dateCells
时上下滚动
- 选中不包含
activities
的dateCells
时上下滚动
Whenever a dateCell
that contains activities
are selected, the cells are no longer cleaned up, ie the dots starts appearing at random places.看动图:
代码如下:
//At viewController: JTACMonthViewDelegate
func configureCell(view: JTACDayCell?, cellState: CellState) {
guard let cell = view as? DateCell else { return }
cell.dateLabel.text = cellState.text
handleCellTextColor(cell: cell, cellState: cellState)
handleCellSelected(cell: cell, cellState: cellState)
highlightTodaysDate(cell: cell, cellState: cellState)
handleCellEvents(cell: cell, cellState: cellState)
}
func highlightTodaysDate(cell: DateCell, cellState: CellState) {
dateFormatter.dateFormat = "YYYY MM dd"
if dateFormatter.string(from: cellState.date) == dateFormatter.string(from: Date()) {
cell.isToday = true
} else {
cell.isToday = false
}
}
func handleCellTextColor(cell: DateCell, cellState: CellState) {
if cellState.dateBelongsTo == .thisMonth {
cell.dateLabel.textColor = UIColor.black
} else {
cell.dateLabel.textColor = UIColor.gray
}
}
func handleCellSelected(cell: DateCell, cellState: CellState) {
if cellState.isSelected {
cell.selectedView.isHidden = false
dateFormatter.dateFormat = "dd-MMM-yyyy"
let dateString = dateFormatter.string(from: cellState.date)
//a separate tableView is in viewController, here getting dataSource for that TV
let filtered = calendarDataSource.filter { [=10=].key == dateString }
tableViewDataSource = filtered[dateString] ?? []
tableView.reloadData()
} else {
cell.selectedView.isHidden = true
}
}
func handleCellEvents(cell: DateCell, cellState: CellState) {
dateFormatter.dateFormat = "dd-MMM-yyyy"
let dateString = dateFormatter.string(from: cellState.date)
if calendarDataSource[dateString] == nil {
cell.activities = []
} else {
cell.activities = calendarDataSource[dateString]
}
}
//At DateCell
var isToday: Bool? {
didSet {
if isToday ?? false {
//setup red selectedView bg
} else {
//setup gray selectedView bg
}
}
}
var activities: [Activity]? {
didSet {
if let activities = activities {
if activities.count > 0 {
setupStackView(activities)
}
} else {
stackView.removeFromSuperview()
}
}
}
var stackView = UIStackView()
override init(frame: CGRect) {
super.init(frame: frame)
//Other setup work
}
func setupStackView(_ activities: [Activity]) {
var dotViews: [UIView] = activities.map { (activity) -> DotView in
let dotView = DotView()
if activity.type == "1" {
dotView.dotView.backgroundColor = .orange
} else if activity.type == "2" {
dotView.dotView.backgroundColor = .purple
} else {
dotView.dotView.backgroundColor = .lightGray
}
return dotView
}
if activities.count > 1 {
dotViews.insert(UIView(), at: 0)
dotViews.insert(UIView(), at: activities.count + 1)
}
stackView = UIStackView(arrangedSubviews: dotViews)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.distribution = .fillEqually
addSubview(stackView)
stackView.topAnchor.constraint(equalTo: dateLabel.bottomAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
override func prepareForReuse() {
super.prepareForReuse()
//Other UI reset work here
stackView.removeFromSuperview()
}
如何清理单元格,使点不出现在不该出现的地方?
我认为您需要在每次重新加载单元格时删除您的 stackView。不仅仅是当活动为零时。每次加载一个单元格时,您都会想把石板擦干净。
var activities: [Activity]? {
didSet {
stackView.removeFromSuperview()
if let activities = activities {
if activities.count > 0 {
setupStackView(activities)
}
}
}
}
I am attempting to clear the DateCell in prepareForReuse
but my implementation doesn't seem to work when a DateCell
containing Activities
were selected.
我有以下设置:
- 仅 4 月 3 日和 4 月 4 日的虚拟数据
- 当有
activities
时,则在日期下方渲染一个stackView
包含点。
我的实现在以下情况下工作正常,即正确清理和重复使用单元格:
- 未选择
dateCells
时上下滚动 - 选中不包含
activities
的dateCells
时上下滚动
Whenever a dateCell
that contains activities
are selected, the cells are no longer cleaned up, ie the dots starts appearing at random places.看动图:
代码如下:
//At viewController: JTACMonthViewDelegate
func configureCell(view: JTACDayCell?, cellState: CellState) {
guard let cell = view as? DateCell else { return }
cell.dateLabel.text = cellState.text
handleCellTextColor(cell: cell, cellState: cellState)
handleCellSelected(cell: cell, cellState: cellState)
highlightTodaysDate(cell: cell, cellState: cellState)
handleCellEvents(cell: cell, cellState: cellState)
}
func highlightTodaysDate(cell: DateCell, cellState: CellState) {
dateFormatter.dateFormat = "YYYY MM dd"
if dateFormatter.string(from: cellState.date) == dateFormatter.string(from: Date()) {
cell.isToday = true
} else {
cell.isToday = false
}
}
func handleCellTextColor(cell: DateCell, cellState: CellState) {
if cellState.dateBelongsTo == .thisMonth {
cell.dateLabel.textColor = UIColor.black
} else {
cell.dateLabel.textColor = UIColor.gray
}
}
func handleCellSelected(cell: DateCell, cellState: CellState) {
if cellState.isSelected {
cell.selectedView.isHidden = false
dateFormatter.dateFormat = "dd-MMM-yyyy"
let dateString = dateFormatter.string(from: cellState.date)
//a separate tableView is in viewController, here getting dataSource for that TV
let filtered = calendarDataSource.filter { [=10=].key == dateString }
tableViewDataSource = filtered[dateString] ?? []
tableView.reloadData()
} else {
cell.selectedView.isHidden = true
}
}
func handleCellEvents(cell: DateCell, cellState: CellState) {
dateFormatter.dateFormat = "dd-MMM-yyyy"
let dateString = dateFormatter.string(from: cellState.date)
if calendarDataSource[dateString] == nil {
cell.activities = []
} else {
cell.activities = calendarDataSource[dateString]
}
}
//At DateCell
var isToday: Bool? {
didSet {
if isToday ?? false {
//setup red selectedView bg
} else {
//setup gray selectedView bg
}
}
}
var activities: [Activity]? {
didSet {
if let activities = activities {
if activities.count > 0 {
setupStackView(activities)
}
} else {
stackView.removeFromSuperview()
}
}
}
var stackView = UIStackView()
override init(frame: CGRect) {
super.init(frame: frame)
//Other setup work
}
func setupStackView(_ activities: [Activity]) {
var dotViews: [UIView] = activities.map { (activity) -> DotView in
let dotView = DotView()
if activity.type == "1" {
dotView.dotView.backgroundColor = .orange
} else if activity.type == "2" {
dotView.dotView.backgroundColor = .purple
} else {
dotView.dotView.backgroundColor = .lightGray
}
return dotView
}
if activities.count > 1 {
dotViews.insert(UIView(), at: 0)
dotViews.insert(UIView(), at: activities.count + 1)
}
stackView = UIStackView(arrangedSubviews: dotViews)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.distribution = .fillEqually
addSubview(stackView)
stackView.topAnchor.constraint(equalTo: dateLabel.bottomAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
override func prepareForReuse() {
super.prepareForReuse()
//Other UI reset work here
stackView.removeFromSuperview()
}
如何清理单元格,使点不出现在不该出现的地方?
我认为您需要在每次重新加载单元格时删除您的 stackView。不仅仅是当活动为零时。每次加载一个单元格时,您都会想把石板擦干净。
var activities: [Activity]? {
didSet {
stackView.removeFromSuperview()
if let activities = activities {
if activities.count > 0 {
setupStackView(activities)
}
}
}
}