My problem video: https://streamable.com/2vrdbu
As you move around the "Collection View" the objects move around and the assignment doesn't work properly.
I tried many methods, but I could not achieve successful results.
Code blocks:
UIViewController:
class BeadsViewController: UIViewController {
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 10
layout.sectionInset = .init(top: 0, left: 0, bottom: 0, right: 0)
return layout
}()
private lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(BeadsCell.self, forCellWithReuseIdentifier: BeadsCell.reuseID)
collectionView.backgroundColor = .clear
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
return collectionView
}()
Extension for CollectionView
Extension View Controller: (UICollectionViewCell Delegate etc.)
extension BeadsViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return beadsList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item = collectionView.dequeueReusableCell(withReuseIdentifier: BeadsCell.reuseID, for: indexPath) as! BeadsCell
incomingIndex = indexPath.item + 1
let beads = beadsList[indexPath.item]
item.setGenerate(item: Beads(imageName: beads.imageName, isPremium: beads.isPremium))
return item
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width: CGFloat = (collectionViewWidth - 38) / CGFloat(3)
let height: CGFloat
switch screenHeight {
case 667: // SE 2nd gen, 8, 7, 6s, 6
height = (160 * screenHeight) / 926
case 736: // 8 plus
height = (150 * screenHeight) / 926
default:
height = (163 * screenHeight) / 926 // 13 pro max - 12 pro max
}
return CGSize(width: width, height: height)
}
}
Cell:
class BeadsCell: UICollectionViewCell {
static let reuseID = "beadsCell"
lazy var backgroundArea: UIImageView = {
let bgArea = UIImageView()
bgArea.layer.cornerRadius = 10
bgArea.image = UIImage(named: "lockBeadBG")?.withRenderingMode(.alwaysOriginal)
return bgArea
}()
lazy var imageArea: UIImageView = {
let imageArea = UIImageView()
imageArea.contentMode = .scaleAspectFit
return imageArea
}()
lazy var lockImage: UIImageView = {
let imageArea = UIImageView()
imageArea.contentMode = .scaleAspectFit
imageArea.image = UIImage(named: "lockImage")?.withRenderingMode(.alwaysOriginal)
return imageArea
}()
lazy var openImage: UIImageView = {
let imageArea = UIImageView()
imageArea.contentMode = .scaleAspectFit
imageArea.image = UIImage(named: "unlcokBtn")?.withRenderingMode(.alwaysOriginal)
return imageArea
}()
lazy var openText: UILabel = {
let label = UILabel()
label.text = "Open"
label.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
label.font = UIFont(name: "CeraPro-Bold", size: 15.2)
return label
}()
func setGenerate(item: Beads) {
if(item.isPremium == false){
imageArea.image = UIImage(named: item.imageName!)?.withRenderingMode(.alwaysOriginal)
} else if (item.isPremium == true) {
imageArea.image = UIImage(named: item.imageName!)?.withRenderingMode(.alwaysOriginal)
}
}
lazy var screenHeight = UIScreen.main.bounds.height
lazy var screenWidth = UIScreen.main.bounds.width
func beadsCellLayout(){
addSubview(backgroundArea)
if (beadsList[incomingIndex].isPremium == false) {
backgroundArea.anchor(top: contentView.topAnchor, bottom: contentView.bottomAnchor, leading: contentView.leadingAnchor, trailing: contentView.trailingAnchor, size: .init(width: (120 * screenWidth / 428), height: (163 * screenHeight / 926)))
backgroundArea.addSubview(imageArea)
imageArea.anchor(top: nil, bottom: nil, leading: nil, trailing: nil, size: .init(width: (75 * screenWidth / 428 ), height: (75 * screenHeight / 926)))
imageArea.centerXAnchor.constraint(equalTo: backgroundArea.centerXAnchor).isActive = true
imageArea.centerYAnchor.constraint(equalTo: backgroundArea.centerYAnchor).isActive = true
} else {
backgroundArea.anchor(top: contentView.topAnchor, bottom: contentView.bottomAnchor, leading: contentView.leadingAnchor, trailing: contentView.trailingAnchor, size: .init(width: (120 * screenWidth / 428), height: (163 * screenHeight / 926)))
backgroundArea.addSubview(imageArea)
imageArea.anchor(top: backgroundArea.topAnchor, bottom: nil, leading: nil, trailing: nil, padding: .init(top: 25, left: 0, bottom: 0, right: 0))
imageArea.centerXAnchor.constraint(equalTo: backgroundArea.centerXAnchor).isActive = true
backgroundArea.addSubview(lockImage)
lockImage.anchor(top: nil, bottom: nil, leading: imageArea.leadingAnchor, trailing: nil, padding: .init(top: 0, left: (22 * screenWidth / 428), bottom: 0, right: 0))
lockImage.centerYAnchor.constraint(equalTo: imageArea.centerYAnchor).isActive = true
backgroundArea.addSubview(openImage)
openImage.anchor(top: nil, bottom: backgroundArea.bottomAnchor, leading: nil, trailing: nil, padding: .init(top: 0, left: 0, bottom: 10, right: 0))
openImage.centerXAnchor.constraint(equalTo: backgroundArea.centerXAnchor).isActive = true
openImage.addSubview(openText)
openText.anchor(top: openImage.topAnchor, bottom: nil, leading: openImage.leadingAnchor, trailing: nil, padding: .init(top: 13, left: 40, bottom: 0, right: 0))
}
}
override init(frame: CGRect) {
super.init(frame: frame)
beadsCellLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/*override func prepareForReuse() {
//super.prepareForReuse()
backgroundArea.image = nil
imageArea.image = nil
lockImage.image = nil
openImage.image = nil
openText.text = nil
}*/
}
In this case, you should use two different cells for the collectionview.
One for current cells and one for premium ones