I am trying to create collectionView cells programmatically and add constraints to the subviews in code. I am unsure at what point in the code I need to add this.
I want my cell to have a view with a rounder corner, within that, I have a vertical stackview which contains an image and a label.
I had this looking nice but there was an issue with the label going beyond the bounds of the stackview. So I need to add constraints to this label but when I do so, I am getting a crash and XCode asks if the constraint reference something from outside the subtree of the view.
Code below:
final class myCollectionViewCell: UICollectionViewCell {
// MARK: - Properties
var colorView: UIView!
var label: UILabel!
var img: UIImageView!
// MARK: - Object Lifecycle
override init(frame: CGRect) {
super.init(frame: frame)
self.colorView = UIView()
colorView.layer.cornerRadius = 8
let stackView = UIStackView()
stackView.axis = UILayoutConstraintAxis.vertical
stackView.distribution = UIStackViewDistribution.fill
stackView.alignment = UIStackViewAlignment.center
stackView.spacing = 16.0
stackView.center = self.contentView.center
self.label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.widthAnchor.constraint(equalToConstant: self.contentView.frame.width).isActive = true
label.textAlignment = .center
self.img = UIImageView()
img.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
img.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
stackView.addArrangedSubview(img)
stackView.addArrangedSubview(label)
stackView.translatesAutoresizingMaskIntoConstraints = false
label.addConstraint(NSLayoutConstraint(item: stackView, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 20))
label.addConstraint(NSLayoutConstraint(item: stackView, attribute: .leading, relatedBy: .equal, toItem: label, attribute: .leading, multiplier: 1, constant: 20))
self.colorView.addSubview(stackView)
self.contentView.addSubview(self.colorView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Layout
override func layoutSubviews() {
super.layoutSubviews()
self.label.sizeToFit()
self.img.layer.cornerRadius = self.img.frame.width/2
self.img.clipsToBounds = true
self.colorView.frame = CGRect(origin: CGPoint.zero, size: self.contentView.bounds.size)
}
override class var requiresConstraintBasedLayout: Bool {
return false
}
}
Also my image view only becomes rounded on scroll. Where should I be placing the cornerRadius and clipsToBounds property?
Here is some extra info about the collectionView layout:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemWidth : CGFloat = 100
let itemHeight : CGFloat = 250.0
return CGSize(width: itemWidth, height: itemHeight)
}

internal(docs). According to this, you can remove extrainternals in your code.