Swift 3.2 中 cellForItemAt 日期的 JTAppleCalendar 自定义单元格错误
JTAppleCalendar Custom cell bug on cellForItemAt date in Swift 3.2
我在我的项目中添加了 JTAppleCalendar
,我想在我的一些日历单元格中添加一些标签。我成功添加了它们,但是当我在我的日历月份向左或向右滚动时,标签内的单元格消失、隐藏或混合,当我一次又一次滚动时,混合越来越多。我需要任何协议或代表等吗?或者,这只是一个错误?
How can I fix that bug?
我的cellForItemAt
代码:
func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
let cell = calendar.dequeueReusableCell(withReuseIdentifier: "CellView", for: indexPath) as! CellView
var currentdate = String(describing: myCalendar.date(byAdding: .day, value: 1, to: cellState.date))
currentdate = currentdate.substring(from: 9, length: 10)
cell.tagList.tags.removeAll()
cell.tagList.hide()
cell.contentView.backgroundColor = nil
cell.tagList.alpha = 0
cell.tagList.numberOfRows = 0
cell.tagList.backgroundColor = UIColor.clear
cell.tagList.isHidden = true
var i : Int
i = 0
for object in datas {
i = i + 1
let clean = "\(object)".components(separatedBy: "*")
if clean[0] == currentdate {
let gotag : Int
gotag = Int(clean[1])!
cell.tagList.isHidden = false
cell.dayLabel.text = cellState.text
cell.contentView.backgroundColor = UIColor.gray
let itemName = "Item name \(i)"
cell.tagList.alpha = 1
if clean[1] == "1" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.orange,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "2" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.green,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "3" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.brown,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "4" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.black,textColor: UIColor.white,comesTag: gotag)
}
}else{
cell.tagList.backgroundColor = UIColor.clear
}
}
handleCellConfiguration(cell: cell, cellState: cellState)
return cell
}
正在执行的错误:
https://github.com/LetSwiftDev/CalendarBug/blob/master/calendarbug.gif
您也可以在这里加入官方 JTAppleCalendar 聊天
https://gitter.im/patchthecode/JTAppleCalendar
我不知道这是否是真正的问题,但您错过了一个功能。
实现 willDisplayCell
函数,如下所示 -> https://github.com/patchthecode/JTAppleCalendar/issues/553
这可能会解决您的问题。
但奇怪的是,您自定义的框架工作不会警告您忘记实现该功能。
基本上,要制作一个奇怪的 "workaround" 你应该实现 classic UICollectionView(JTAppleCalendar 来自它)willDisplay
method, that , as you can see , in theory it should be used to detect cell additions instead of replicate it's content, so to make this re-build of content you can follow the example also explained to the JTAppleCalendar gitHub issues and reported by swift nub 在本页 .
因此,您的代码可以是:
ViewController.swift:
extension ViewController: JTAppleCalendarViewDelegate, JTAppleCalendarViewDataSource {
func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {
var cell = cell as! CellView
cell = sharedFunctionToConfigureCell(cell: cell, cellState: cellState, date: date)
}
func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
var cell = calendar.dequeueReusableCell(withReuseIdentifier: "CellView", for: indexPath) as! CellView
cell = sharedFunctionToConfigureCell(cell: cell, cellState: cellState, date: date)
return cell
}
func sharedFunctionToConfigureCell(cell: CellView, cellState: CellState, date: Date)-> CellView {
var currentdate = String(describing: myCalendar.date(byAdding: .day, value: 1, to: cellState.date))
currentdate = currentdate.substring(from: 9, length: 10)
cell.tagList.tags.removeAll()
cell.tagList.hide()
cell.contentView.backgroundColor = nil
cell.tagList.alpha = 0
cell.tagList.numberOfRows = 0
cell.tagList.backgroundColor = UIColor.clear
cell.tagList.isHidden = true
var i : Int
i = 0
for object in datas {
i = i + 1
let clean = "\(object)".components(separatedBy: "*")
if clean[0] == currentdate {
let gotag : Int
gotag = Int(clean[1])!
cell.tagList.isHidden = false
cell.dayLabel.text = cellState.text
cell.contentView.backgroundColor = UIColor.gray
let itemName = "Item name \(i)"
cell.tagList.alpha = 1
if clean[1] == "1" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.orange,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "2" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.green,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "3" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.brown,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "4" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.black,textColor: UIColor.white,comesTag: gotag)
}
}else{
cell.tagList.backgroundColor = UIColor.clear
}
}
handleCellConfiguration(cell: cell, cellState: cellState)
return cell
}
// your other code..
更新(测试后):
根据您的意见,我决定深入分析您的代码。
首先,您的 mainStoryBoard 中有一个小错误,您可以很容易地更正它,用 UIButton
替换 DesignableButton
(不存在的 class),如图所示,以避免错误:CalendarBug[9879:1645088] Unknown class _TtC11CalendarBug16DesignableButton in Interface Builder file
.
之后,完整的 JTAppleCaledar
库似乎没有任何问题,实际上作者还扩展了 willDisplay
委托,解决了单元格渲染的许多问题。
我在 TagListView.swift
class 中发现了您的问题,更准确地说是在 reset
.
方法中
TagListView.swift:
func reset() {
for tag in tags {
tag.removeFromSuperview()
}
tags = []
currentRow = 0
numberOfRows = 0
}
此方法从 superview 中删除所有标签列表(标签数组),但不删除过去添加到 superview 的其他标签,换句话说,仅包含数组 tags
中的标签。所以,为了避免这个问题,你可以通过在线添加来加强你的 reset
方法(我们知道它们是 UILabel
所以不需要知道它们所有的 tag
号码):
func reset() {
for tag in tags {
tag.removeFromSuperview()
}
tags = []
currentRow = 0
numberOfRows = 0
self.subviews.forEach({ if [=12=] is UILabel { [=12=].removeFromSuperview()} })
}
要优化您的代码,您只需将此方法更正为:
func reset(){
tags = []
currentRow = 0
numberOfRows = 0
self.subviews.forEach({ if [=13=] is UILabel { [=13=].removeFromSuperview()} })
}
输出:
我在我的项目中添加了 JTAppleCalendar
,我想在我的一些日历单元格中添加一些标签。我成功添加了它们,但是当我在我的日历月份向左或向右滚动时,标签内的单元格消失、隐藏或混合,当我一次又一次滚动时,混合越来越多。我需要任何协议或代表等吗?或者,这只是一个错误?
How can I fix that bug?
我的cellForItemAt
代码:
func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
let cell = calendar.dequeueReusableCell(withReuseIdentifier: "CellView", for: indexPath) as! CellView
var currentdate = String(describing: myCalendar.date(byAdding: .day, value: 1, to: cellState.date))
currentdate = currentdate.substring(from: 9, length: 10)
cell.tagList.tags.removeAll()
cell.tagList.hide()
cell.contentView.backgroundColor = nil
cell.tagList.alpha = 0
cell.tagList.numberOfRows = 0
cell.tagList.backgroundColor = UIColor.clear
cell.tagList.isHidden = true
var i : Int
i = 0
for object in datas {
i = i + 1
let clean = "\(object)".components(separatedBy: "*")
if clean[0] == currentdate {
let gotag : Int
gotag = Int(clean[1])!
cell.tagList.isHidden = false
cell.dayLabel.text = cellState.text
cell.contentView.backgroundColor = UIColor.gray
let itemName = "Item name \(i)"
cell.tagList.alpha = 1
if clean[1] == "1" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.orange,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "2" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.green,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "3" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.brown,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "4" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.black,textColor: UIColor.white,comesTag: gotag)
}
}else{
cell.tagList.backgroundColor = UIColor.clear
}
}
handleCellConfiguration(cell: cell, cellState: cellState)
return cell
}
正在执行的错误:
https://github.com/LetSwiftDev/CalendarBug/blob/master/calendarbug.gif
您也可以在这里加入官方 JTAppleCalendar 聊天 https://gitter.im/patchthecode/JTAppleCalendar
我不知道这是否是真正的问题,但您错过了一个功能。
实现 willDisplayCell
函数,如下所示 -> https://github.com/patchthecode/JTAppleCalendar/issues/553
这可能会解决您的问题。 但奇怪的是,您自定义的框架工作不会警告您忘记实现该功能。
基本上,要制作一个奇怪的 "workaround" 你应该实现 classic UICollectionView(JTAppleCalendar 来自它)willDisplay
method, that , as you can see , in theory it should be used to detect cell additions instead of replicate it's content, so to make this re-build of content you can follow the example also explained to the JTAppleCalendar gitHub issues and reported by swift nub
因此,您的代码可以是:
ViewController.swift:
extension ViewController: JTAppleCalendarViewDelegate, JTAppleCalendarViewDataSource {
func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {
var cell = cell as! CellView
cell = sharedFunctionToConfigureCell(cell: cell, cellState: cellState, date: date)
}
func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
var cell = calendar.dequeueReusableCell(withReuseIdentifier: "CellView", for: indexPath) as! CellView
cell = sharedFunctionToConfigureCell(cell: cell, cellState: cellState, date: date)
return cell
}
func sharedFunctionToConfigureCell(cell: CellView, cellState: CellState, date: Date)-> CellView {
var currentdate = String(describing: myCalendar.date(byAdding: .day, value: 1, to: cellState.date))
currentdate = currentdate.substring(from: 9, length: 10)
cell.tagList.tags.removeAll()
cell.tagList.hide()
cell.contentView.backgroundColor = nil
cell.tagList.alpha = 0
cell.tagList.numberOfRows = 0
cell.tagList.backgroundColor = UIColor.clear
cell.tagList.isHidden = true
var i : Int
i = 0
for object in datas {
i = i + 1
let clean = "\(object)".components(separatedBy: "*")
if clean[0] == currentdate {
let gotag : Int
gotag = Int(clean[1])!
cell.tagList.isHidden = false
cell.dayLabel.text = cellState.text
cell.contentView.backgroundColor = UIColor.gray
let itemName = "Item name \(i)"
cell.tagList.alpha = 1
if clean[1] == "1" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.orange,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "2" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.green,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "3" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.brown,textColor: UIColor.white,comesTag: gotag)
}else if clean[1] == "4" {
cell.tagList.addTag(itemName, target: self, tapAction: #selector(ViewController.tap(_:)), longPressAction: #selector(ViewController.tap(_:)),backgroundColor: UIColor.black,textColor: UIColor.white,comesTag: gotag)
}
}else{
cell.tagList.backgroundColor = UIColor.clear
}
}
handleCellConfiguration(cell: cell, cellState: cellState)
return cell
}
// your other code..
更新(测试后):
根据您的意见,我决定深入分析您的代码。
首先,您的 mainStoryBoard 中有一个小错误,您可以很容易地更正它,用 UIButton
替换 DesignableButton
(不存在的 class),如图所示,以避免错误:CalendarBug[9879:1645088] Unknown class _TtC11CalendarBug16DesignableButton in Interface Builder file
.
之后,完整的 JTAppleCaledar
库似乎没有任何问题,实际上作者还扩展了 willDisplay
委托,解决了单元格渲染的许多问题。
我在 TagListView.swift
class 中发现了您的问题,更准确地说是在 reset
.
TagListView.swift:
func reset() {
for tag in tags {
tag.removeFromSuperview()
}
tags = []
currentRow = 0
numberOfRows = 0
}
此方法从 superview 中删除所有标签列表(标签数组),但不删除过去添加到 superview 的其他标签,换句话说,仅包含数组 tags
中的标签。所以,为了避免这个问题,你可以通过在线添加来加强你的 reset
方法(我们知道它们是 UILabel
所以不需要知道它们所有的 tag
号码):
func reset() {
for tag in tags {
tag.removeFromSuperview()
}
tags = []
currentRow = 0
numberOfRows = 0
self.subviews.forEach({ if [=12=] is UILabel { [=12=].removeFromSuperview()} })
}
要优化您的代码,您只需将此方法更正为:
func reset(){
tags = []
currentRow = 0
numberOfRows = 0
self.subviews.forEach({ if [=13=] is UILabel { [=13=].removeFromSuperview()} })
}
输出: