ios - 一次选择多个单元格的 UIcollection 视图错误
问题描述
我正在创建一个 7 天的日历。我正在使用包含 7 个单元格的集合视图,但是当我选择集合视图的最后一个单元格并滚动到第一个单元格时,最后一个单元格保持选中状态,并且第一个单元格也被选中。这是我得到的错误的屏幕截图。在此处输入图像描述 在此处输入图像描述 这是我的主视图控制器中的代码
`import UIKit
import Foundation
class ScheduleViewController: UIViewController {
let top = UIColor(red: 217/255, green: 30/255, blue: 133/255, alpha: 1)
let bottom = UIColor(red: 242/255, green: 56/255, blue: 15/255, alpha: 1)
let todayColor = UIColor(red: 242/255, green: 56/255, blue: 15/255, alpha: 1)
// let otherDayColor = UIColor(red: 90/255, green: 90/255, blue: 90/255, alpha: 1)
let otherDayColor = UIColor(red: 242/255, green: 56/255, blue: 15/255, alpha: 1)
var now = Date()
var day = DateFormatter()
let dateHeading: UILabel = {
let heading = UILabel()
heading.text = "Date"
heading.font = UIFont(name: "Roboto-Medium", size: 20)
heading.translatesAutoresizingMaskIntoConstraints = false
heading.numberOfLines = 0
heading.adjustsFontSizeToFitWidth = true
return heading
}()
fileprivate let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .clear
cv.translatesAutoresizingMaskIntoConstraints = false
cv.register(CalendarCell.self, forCellWithReuseIdentifier: "CellID")
return cv
}()
let bookButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Book", for: .normal)
button.titleLabel?.font = UIFont(name: "Roboto-Medium", size: 22)
button.layer.cornerRadius = 5
button.setTitleColor(.white, for: .normal)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
setupNavigationBar()
view.addSubview(bookButton)
bookButtonLayout()
view.addSubview(collectionView)
collectionViewLayout()
configureCollectionView()
collectionView.selectItem(at: IndexPath(row: 0, section: 0), animated: true, scrollPosition: [])
view.addSubview(dateHeading)
dateHeadingLayout()
let gradientWidth = (UIScreen.main.bounds.width - 40)
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [top.cgColor, bottom.cgColor]
gradientLayer.locations = [0.15, 1]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 0)
gradientLayer.frame = CGRect(x: 0, y: 0, width: gradientWidth, height: 44)
gradientLayer.cornerRadius = 5
bookButton.layer.insertSublayer(gradientLayer, at: 0)
}
func myCalender(numDay: Int) -> Date {
var dateComponents = DateComponents()
dateComponents.setValue(numDay, for: .day); // +1 day
let tomorrow = Calendar.current.date(byAdding: dateComponents, to: now)
return tomorrow!
}
func setupNavigationBar(){
self.navigationItem.title = "Schedule"
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
}
func collectionViewLayout(){
collectionView.heightAnchor.constraint(equalToConstant: 85).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
}
func configureCollectionView(){
collectionView.delegate = self
collectionView.dataSource = self
}
func dateHeadingLayout(){
dateHeading.heightAnchor.constraint(equalToConstant: 26).isActive = true
dateHeading.widthAnchor.constraint(equalToConstant: 42).isActive = true
dateHeading.bottomAnchor.constraint(equalTo: collectionView.topAnchor, constant: -5).isActive = true
dateHeading.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
}
func bookButtonLayout(){
bookButton.heightAnchor.constraint(equalToConstant: 44).isActive = true
bookButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
bookButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
bookButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -30).isActive = true
}
}
extension ScheduleViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 70, height: 75)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as? CalendarCell
if cell?.isSelected == true{
cell?.backgroundColor = todayColor
cell?.dateLabel.textColor = UIColor.white.withAlphaComponent(1)
cell?.dayLabel.textColor = UIColor.white.withAlphaComponent(1)
cell?.isOpaque = false
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as? CalendarCell
if cell?.isSelected == false{
cell?.backgroundColor = .clear
cell?.dateLabel.textColor = UIColor.white.withAlphaComponent(0.5)
cell?.dayLabel.textColor = UIColor.white.withAlphaComponent(0.5)
cell?.isOpaque = false
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellID", for: indexPath) as! CalendarCell
cell.layer.cornerRadius = 5
cell.dateLabel.textColor = UIColor.white.withAlphaComponent(0.5)
cell.dayLabel.textColor = UIColor.white.withAlphaComponent(0.5)
cell.isOpaque = false
if cell.isSelected == true{
cell.backgroundColor = todayColor
cell.dateLabel.textColor = UIColor.white.withAlphaComponent(1)
cell.dayLabel.textColor = UIColor.white.withAlphaComponent(1)
cell.isOpaque = false
}
if indexPath.row == 0{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: Date()) - 1])
cell.dateLabel.text = now.string(format: "dd")
}
else if indexPath.row == 1{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: myCalender(numDay: 1)) - 1])
cell.dateLabel.text = myCalender(numDay: 1).string(format: "dd")
}
else if indexPath.row == 2{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: myCalender(numDay: 2)) - 1])
cell.dateLabel.text = myCalender(numDay: 2).string(format: "dd")
}
else if indexPath.row == 3{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: myCalender(numDay: 3)) - 1])
cell.dateLabel.text = myCalender(numDay: 3).string(format: "dd")
}
else if indexPath.row == 4{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: myCalender(numDay: 4)) - 1])
cell.dateLabel.text = myCalender(numDay: 4).string(format: "dd")
}
else if indexPath.row == 5{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: myCalender(numDay: 5)) - 1])
cell.dateLabel.text = myCalender(numDay: 5).string(format: "dd")
}
else if indexPath.row == 6{
cell.dayLabel.text = (day.shortWeekdaySymbols[Calendar.current.component(.weekday, from: myCalender(numDay: 6)) - 1])
cell.dateLabel.text = myCalender(numDay: 6).string(format: "dd")
}
cell.isSelected = (cellStatus[indexPath.row] as? Bool) ?? false
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}
extension Date {
func string(format: String) -> String {
let formatter = DateFormatter()
formatter.timeZone = .current
formatter.dateFormat = format
formatter.shortWeekdaySymbols = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
return formatter.string(from: self)
}
}`
这是我的自定义日历单元的代码
`import UIKit
class CalendarCell: UICollectionViewCell {
let dateLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont(name: "Roboto-Medium", size: 30)
label.textColor = .white
label.textAlignment = .center
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0
return label
}()
let dayLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont(name: "Roboto-Medium", size: 20)
label.textColor = .white
label.textAlignment = .center
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.layer.cornerRadius = 5
contentView.addSubview(dayLabel)
dayLabelLayout()
contentView.addSubview(dateLabel)
dateLabelLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func dateLabelLayout(){
dateLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true
dateLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true
dateLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5).isActive = true
dateLabel.bottomAnchor.constraint(equalTo: dayLabel.topAnchor).isActive = true
}
func dayLabelLayout(){
dayLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
dayLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true
dayLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5).isActive = true
dayLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
}
}
`
解决方案
该单元格被重用未选中......但由于重用......它的 backgroundColor , dateLabel , dayLabel 和 isOpaque 改变
在您的CalendarCell
.. 中,使用非选定单元格的默认值覆盖此函数 ..
override func prepareForReuse() {
super.prepareForReuse()
backgroundColor = .white//defaultValue
dateLabel.textColor = UIColor.white.withAlphaComponent(1) // default value
cell?.dayLabel.textColor = UIColor.white.withAlphaComponent(1) // default value
cell?.isOpaque = false // default value
}
推荐阅读
- sql - 检索最新日期预言机
- android - 如何通过下拉刷新 Expo Webview 中的页面?
- google-cloud-platform - 是否可以在 Cloud Run 服务中公开 5001 (HTTP) 和 5672 (TCP) 端口?
- pulp - 约束:我可以融化克数、卡路里和百分比作为约束吗?
- php - PHP 帮助、MySQL 和查询中的行号
- python - Convertapi 模块在调用时启动多个 tkinter 实例
- xquery - 当我尝试在 MarkLogic 中删除集合时出现超时错误
- javascript - 如何使用 React 创建表单帖子?
- swift - 为多个枚举创建一个 DRY 函数(枚举子类化?)
- javascript - 我正在删除课程并设置另一个课程,但它没有发生?