Reputation: 1255
Im currently have a horizontal collection view. I currently have multiple selection enabled set to off. For some reason when I select the first item the item toward the end of the collectionView also become selected. Thank you for the hep.
protocol customDatePickerDelegate:class {
func dateFromCustomDatePicker(date:Date)
}
class datePickerCollectionViewCell:UICollectionViewCell {
var labelNumber:UILabel = UILabel()
var minuteLabel:UILabel = {
let v = UILabel()
v.text = "Minutes"
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .white
minuteLabel.labelFormCustom(labelType: .dateForm)
labelNumber.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(labelNumber)
labelNumber.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0).isActive = true
labelNumber.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0).isActive = true
minuteLabel.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(minuteLabel)
minuteLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0).isActive = true
minuteLabel.topAnchor.constraint(equalTo: labelNumber.bottomAnchor, constant: 0).isActive = true
self.layer.cornerRadius = 6
self.layer.borderWidth = 0.5
self.layer.borderColor = UIColor(red:205.0/255.0, green:205.0/255.0, blue:205.0/255.0, alpha: 1.0).cgColor
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class NewRquestDatePickerCollectionViewController: UIViewController,UICollectionViewDelegate {
var collectionView:UICollectionView!
override func viewDidLoad() {
setupCollectionView()
}
lazy var centerView:UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.heightAnchor.constraint(equalToConstant: 300).isActive = true
v.backgroundColor = .white
v.addBorderCustom(.bottom)
return v
}()
lazy var durationLabel:UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.textAlignment = .center
v.font = v.font.withSize(17)
return v
}()
lazy var topActionBar:UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.heightAnchor.constraint(equalToConstant: 60).isActive = true
v.backgroundColor = UIColor(hex: "F9F9F9")
v.addBorderCustom(.top)
v.addBorderCustom(.bottom)
return v
}()
lazy var doneButton:UIButton! = {
let v = UIButton(type:.system)
v.translatesAutoresizingMaskIntoConstraints = false
v.setTitle("Done", for: .normal)
v.addTarget(self, action: #selector(doneButtonPressed), for: .touchUpInside)
return v
}()
lazy var cancelButton:UIButton = {
let v = UIButton(type:.system)
v.translatesAutoresizingMaskIntoConstraints = false
v.setTitle("Cancel", for: .normal)
v.addTarget(self, action: #selector(dismissCurrentView), for: .touchUpInside)
return v
}()
lazy var dayLabel:UILabel = {
let v = UILabel()
// v.text = "Monday"
return v
}()
lazy var titleView:UILabel = {
let v = UILabel()
v.text = "Select a deadline"
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
var selectedIndexPath: NSIndexPath?
// var selectedTime:Int!
var timer = Timer()
var timeSeleted:TimeInterval = 10.0
let timeArray:[TimeInterval] = [10,20,30,45,60,140,400,900,1200]
var delegate:customDatePickerDelegate!
var dateSelected:Date!
func setupCollectionView(){
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
//collection view setup
self.view.addSubview(centerView)
centerView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true
centerView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true
centerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout)
collectionView.register(datePickerCollectionViewCell.self, forCellWithReuseIdentifier: "imageCell")
collectionView.delegate = self
collectionView.dataSource = self
centerView.addSubview(topActionBar)
topActionBar.heightAnchor.constraint(equalToConstant: 49).isActive = true
topActionBar.leftAnchor.constraint(equalTo: self.centerView.leftAnchor, constant: 0).isActive = true
topActionBar.rightAnchor.constraint(equalTo: self.centerView.rightAnchor, constant: 0).isActive = true
topActionBar.topAnchor.constraint(equalTo: self.centerView.topAnchor, constant: 0).isActive = true
topActionBar.addSubview(cancelButton)
topActionBar.addSubview(titleView)
cancelButton.leftAnchor.constraint(equalTo: topActionBar.leftAnchor, constant: 16).isActive = true
cancelButton.centerYAnchor.constraint(equalTo: topActionBar.centerYAnchor, constant: 0).isActive = true
titleView.centerXAnchor.constraint(equalTo: topActionBar.centerXAnchor, constant: 0).isActive = true
titleView.centerYAnchor.constraint(equalTo: topActionBar.centerYAnchor, constant: 0).isActive = true
centerView.addSubview(doneButton)
centerView.addBorderCustom(.bottom)
doneButton.centerXAnchor.constraint(equalTo: centerView.centerXAnchor, constant: 0).isActive = true
doneButton.bottomAnchor.constraint(equalTo: centerView.bottomAnchor, constant: -20).isActive = true
centerView.addBorderCustom(.bottom)
centerView.addSubview(collectionView)
collectionView.heightAnchor.constraint(equalToConstant: 100).isActive = true
collectionView.leftAnchor.constraint(equalTo: self.centerView.leftAnchor, constant: 0).isActive = true
collectionView.rightAnchor.constraint(equalTo: self.centerView.rightAnchor, constant: 0).isActive = true
collectionView.topAnchor.constraint(equalTo: self.topActionBar.bottomAnchor, constant: 0).isActive = true
dayLabel.translatesAutoresizingMaskIntoConstraints = false
centerView.addSubview(dayLabel)
dayLabel.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor, constant: 0).isActive = true
dayLabel.topAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: 20).isActive = true
centerView.addSubview(durationLabel)
durationLabel.leftAnchor.constraint(equalTo: self.centerView.leftAnchor, constant: 0).isActive = true
durationLabel.rightAnchor.constraint(equalTo: self.centerView.rightAnchor, constant: 0).isActive = true
durationLabel.topAnchor.constraint(equalTo: self.collectionView.bottomAnchor, constant: 0).isActive = true
durationLabel.bottomAnchor.constraint(equalTo: self.doneButton.topAnchor, constant: 20).isActive = true
timerStart()
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
collectionView.isPagingEnabled = true
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = UIColor(hex:"EFF3F4")
centerView.addBorderCustom(.bottom)
collectionView.allowsMultipleSelection = false
}
}
extension NewRquestDatePickerCollectionViewController {
func dismissCurrentView(){
self.dismiss(animated: true , completion: nil)
}
func doneButtonPressed(){
delegate.dateFromCustomDatePicker(date: dateSelected)
dismissCurrentView()
}
func tappedDeadlineSelection(){
}
func timerStart(){
if #available(iOS 10.0, *) {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in
let date = Date()
let adjustedDate = date.addingTimeInterval(self.timeSeleted * 60.0)
self.dateSelected = adjustedDate
self.durationLabel.text = String(describing: adjustedDate.string(withFormat: "MM/dd/yy, h:mm a"))
self.dayLabel.text = String(describing: adjustedDate.string(withFormat: "EEEE"))
})
} else {
// Fallback on earlier versions
}
}
}
extension NewRquestDatePickerCollectionViewController:UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return timeArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath) as! datePickerCollectionViewCell
cell.awakeFromNib()
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cellInfo = cell as! datePickerCollectionViewCell
//converTime
cellInfo.labelNumber.text = String(self.timeArray[indexPath.row])
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! datePickerCollectionViewCell
let timeAdded = self.timeArray[indexPath.row]
cell.backgroundColor = UIColor(hex: "F2784B")
// let timeAdded = self.timeArray[indexPath.row]
cell.labelNumber.textColor = .white
cell.minuteLabel.textColor = .white
cell.layer.borderColor = UIColor.white.cgColor
timeSeleted = timeAdded
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! datePickerCollectionViewCell
cell.backgroundColor = .white
cell.labelNumber.textColor = .black
cell.minuteLabel.textColor = UIColor().RquestCustomColors(.fontGray)
// collectionView.performBatchUpdates(nil, completion: nil)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 64, height: 64)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 30.0
}
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 30.0
}
}
Upvotes: 0
Views: 569
Reputation: 128
You should make use of the "isSelected" method for the collection view cell. This way you will not have not save any selected indexpath.
So I recommend using this method:
Firstly,
collectionView.allowsMultipleSelection = false
on the UICollectionViewCell you can override the isSelected method
didSet {
if isSelected {
// Change UI for selected state
radioButton.setImage(#imageLiteral(resourceName: "greenTick"), for: .normal)
} else {
// Chage UI for unselected state
radioButton.setImage(#imageLiteral(resourceName: "radioInactive"), for: .normal)
}
}
Finally when you need to find out the indexpath for the selected item.
guard let selectedIndex = self.collectionView.indexPathsForSelectedItems?.first else { return }
Upvotes: 0
Reputation: 448
Because you are reusing existed cell, you should keep track selected item index and update cell state as below:
var selectedIndex: IndexPath?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! datePickerCollectionViewCell
let timeAdded = self.timeArray[indexPath.row]
cell.backgroundColor = UIColor(hex: "F2784B")
// let timeAdded = self.timeArray[indexPath.row]
cell.labelNumber.textColor = .white
cell.minuteLabel.textColor = .white
cell.layer.borderColor = UIColor.white.cgColor
timeSeleted = timeAdded
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
// add the following codes
let lastSelectedIndex = self.selectedIndex
self.selectedIndex = indexPath
// unselect last selected index
collectionView.reloadItems(at: [lastSelectedIndex!])
// reload new selected index
collectionView.reloadItems(at: [self.selectedIndex!])
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cellInfo = cell as! datePickerCollectionViewCell
//converTime
cellInfo.labelNumber.text = String(self.timeArray[indexPath.row])
// add this line of code
cell.isSelected = (self.selectedIndex == indexPath)
}
Upvotes: 1