0
votes

I created a custom UICollection cell but the data sometimes appear in the wrong cell and no matter how much I refresh the UICollection view it refuses to change. I have done a print out to see if the data gotten from the array is wrong but it's not. Is there a way to clear the old data from the cell before inputting the next one. Any suggestion will be appreciated.

custom cell

class customAppointmentViewCell: UICollectionViewCell {

override init(frame: CGRect) {
    super.init(frame: frame)
    setupViews()
}

let thumbnailImageView: UIImageView = {
    let tniv = UIImageView()
    tniv.translatesAutoresizingMaskIntoConstraints = false
    tniv.backgroundColor = UIColor.clear
    tniv.contentMode = .scaleAspectFit
    return tniv
}()

let seperatorView: UIView = {
    let sv = UIView()
    sv.translatesAutoresizingMaskIntoConstraints = false
    sv.backgroundColor = UIColor(r: 11, g: 49, b: 68)
    return sv
}()

let clientNamePlaceHolder: UILabel = {
    let fnhp = UILabel()
    fnhp.translatesAutoresizingMaskIntoConstraints = false
    fnhp.font = UIFont(name: "HelveticaNeue-Medium", size: 17)
    fnhp.textColor = UIColor.white
    fnhp.textAlignment = .left
    return fnhp
}()

let openingTimePlaceHolder: UILabel = {
    let fnhp = UILabel()
    fnhp.translatesAutoresizingMaskIntoConstraints = false
    fnhp.font = UIFont(name: "HelveticaNeue-Medium", size: 12)
    fnhp.textColor = UIColor.white
    fnhp.textAlignment = .left
    return fnhp
}()

let closingTimePlaceHolder: UILabel = {
    let fnhp = UILabel()
    fnhp.translatesAutoresizingMaskIntoConstraints = false
    fnhp.font = UIFont(name: "HelveticaNeue-Medium", size: 12)
    fnhp.textColor = UIColor.white
    fnhp.textAlignment = .left
    return fnhp
}()

let bookedBarberNamePlaceHolder: UILabel = {
    let fnhp = UILabel()
    fnhp.translatesAutoresizingMaskIntoConstraints = false
    fnhp.font = UIFont(name: "HelveticaNeue-Medium", size: 12)
    fnhp.textColor = UIColor.white
    fnhp.textAlignment = .left
    return fnhp
}()

let servicePricePlaceHolder: UILabel = {
    let fnhp = UILabel()
    fnhp.translatesAutoresizingMaskIntoConstraints = false
    fnhp.font = UIFont(name: "HelveticaNeue-Medium", size: 10)
    fnhp.textColor = UIColor.white
    fnhp.textAlignment = .right
    return fnhp
}()

func setupViews(){
    addSubview(thumbnailImageView)
    addSubview(clientNamePlaceHolder)
    addSubview(openingTimePlaceHolder)
    addSubview(closingTimePlaceHolder)
    addSubview(bookedBarberNamePlaceHolder)
    addSubview(servicePricePlaceHolder)
    addSubview(seperatorView)
    backgroundColor = UIColor(r: 23, g: 69, b: 90)
    addContraintsWithFormat(format: "H:|-16-[v0(90)]|", views: thumbnailImageView)
    addContraintsWithFormat(format: "H:|-116-[v0][v1(50)]-10-|", views: clientNamePlaceHolder, servicePricePlaceHolder)
    addContraintsWithFormat(format: "H:|-116-[v0]-60-|", views: openingTimePlaceHolder)
    addContraintsWithFormat(format: "H:|-116-[v0]-60-|", views: closingTimePlaceHolder)
    addContraintsWithFormat(format: "H:|-116-[v0]-60-|", views: bookedBarberNamePlaceHolder)
    addContraintsWithFormat(format: "V:|-10-[v0(20)][v1(20)][v2(20)][v3(20)]-10-|", views: clientNamePlaceHolder, openingTimePlaceHolder,closingTimePlaceHolder, bookedBarberNamePlaceHolder)
    addContraintsWithFormat(format: "V:|-10-[v0(20)]|", views: servicePricePlaceHolder)
    addContraintsWithFormat(format: "V:|-10-[v0]-10-[v1(5)]|", views: thumbnailImageView,seperatorView)
    addContraintsWithFormat(format: "H:|[v0]|", views: seperatorView)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
} 
}

collection view

extension AppointmentsViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.appointments.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! customAppointmentViewCell
    //empty cell data
    //real data

    cell.openingTimePlaceHolder.text = ""
    if let opentime = self.appointments[safe: indexPath.row]?.bookingStartTimeString {
        cell.openingTimePlaceHolder.text = opentime
    } else {
        cell.openingTimePlaceHolder.text = ""
    }


    cell.closingTimePlaceHolder.text = ""
    if let closetime = self.appointments[safe: indexPath.row]?.bookingEndTimeString {
        cell.closingTimePlaceHolder.text = closetime
    } else {
        cell.closingTimePlaceHolder.text = ""
    }


    cell.bookedBarberNamePlaceHolder.text = ""
    if let barberName = self.appointments[safe: indexPath.row]?.bookedBarberName {
        cell.bookedBarberNamePlaceHolder.text = barberName
    } else {
        cell.bookedBarberNamePlaceHolder.text = ""
    }


    cell.servicePricePlaceHolder.text = ""
    if let servicepricee = self.appointments[safe: indexPath.row]?.bookedServicePrice {
        cell.servicePricePlaceHolder.text = servicepricee
    } else {
        cell.servicePricePlaceHolder.text = ""
    }


    cell.thumbnailImageView.image = UIImage()
    if let profileimagess = self.appointments[safe: indexPath.row]?.profileImage {
        cell.thumbnailImageView.image = profileimagess
    } else {
        cell.thumbnailImageView.image = UIImage()
    }


    cell.clientNamePlaceHolder.text = ""
    if let clientnamess = self.appointments[safe: indexPath.row]?.clientName {
        cell.clientNamePlaceHolder.text = clientnamess
    } else {
        cell.clientNamePlaceHolder.text = ""
    }


    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectView.frame.width, height: 100)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if let uuidAvail = UserDefaults.standard.object(forKey: "theOriginalBarberShopUUID") as? String{
        if let bookIDDD = self.appointments[safe: indexPath.row]?.bookingUniqueID {
            let orderDetail = OrderDetailViewController()
            orderDetail.specificAppintment = self.appointments[indexPath.row]
            orderDetail.barberShopID = uuidAvail
            orderDetail.bookingUniqueIDDD = bookIDDD
            orderDetail.bookedBarberUUIDAX = self.appointments[indexPath.row].bookedBarberUUID
            orderDetail.appointmentsviewhold = self
            orderDetail.indexPathSelected = indexPath.row
            navigationController?.pushViewController(orderDetail, animated: true)
        }
    }
}
}

thanks

3
in 'customAppointmentViewCell' class do init your all imageview and label in awakeFromNib() - Ujesh
@Ujesh, I guess Joseph is making cell by purely code and not by xib. - Nikhil Manapure
yes, it's all about code, but he can refresh his subview when every time cell call. so old data will remove when new cell loaded. - Ujesh
HI @Ujesh yes I am making the cell purely by code. But could you please explain how I can refresh the subviews as I think this might help. - Hans Ben

3 Answers

2
votes

Do this in customAppointmentViewCell

override func prepareForReuse() {
    self. thumbnailImageView.image = UIImage()
    //add here other variable and set default value for all.
}

prepareForReuse is called when a new cell will show on screen.

And Remove default value set code from your cellForRow as guided by Nikhil Manapure.

Hope this helps you.

0
votes

Try this -

Implement the method prepareForReuse in your customAppointmentViewCell and in this method remove all the data and reset everything. If you are adding some subView to cell in cellForRow, remove that too.

By doing this you will be able to reduce this-

cell.clientNamePlaceHolder.text = ""
if let clientnamess = self.appointments[safe: indexPath.row]?.clientName {
    cell.clientNamePlaceHolder.text = clientnamess
} else {
    cell.clientNamePlaceHolder.text = ""
}

to this-

if let clientnamess = self.appointments[safe: indexPath.row]?.clientName {
    cell.clientNamePlaceHolder.text = clientnamess
}

After doing this, check if the issue is still there.

Hope this helps :)

-1
votes

Try Passing the model object to the UICollectionViewCell class by assigning a property in cell

example:

UICollectionViewCell:

var object: Model? {
  didSet{
    // here do your assignment of text to various labels
  }
}

CellForRow:

let cell = ...
cell.object = self.appointments[indexPath.item]
return cell

I hope this works.