在程序化collectionviewCell中添加约束

时间:2018-07-14 10:53:13

标签: swift uicollectionview label constraints uicollectionviewcell

我正在尝试以编程方式创建collectionView单元,并将约束添加到代码中的子视图。我不确定在代码中什么时候需要添加它。

我希望我的单元格有一个带有圆角的视图,在其中,我有一个垂直的stackview,其中包含图像和标签。

我看起来很不错,但是标签超出了stackview的范围,这是一个问题。因此,我需要向该标签添加约束,但是这样做时,我崩溃了,XCode询问约束是否从视图的子树外部引用了某些内容。

以下代码:

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
        }
    }

此外,我的图像视图仅在滚动时变为圆形。我应该在哪里放置cornerRadiusclipsToBounds属性?

enter image description here

以下是有关collectionView布局的一些额外信息:

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)
    }

2 个答案:

答案 0 :(得分:2)

要创建带有圆角的imageView,可以使用如下闭合符:

var imageView: UIImageView = {
   let imageView = UIImageView()
   imageView.layer.cornerRadius = 5.0 //Or whatever you want
   imageView.clipsToBounds = true
   return imageView 
 }()

已编辑

首先,将子视图添加到堆栈视图时,无需在其上设置约束。只需为堆栈视图本身设置约束,然后更改其参数即可(例如spacing)。这是图像视图及其下方标签的实现:

 let imageView: UIImageView = {
    let imgView = UIImageView()
    imgView.backgroundColor = .red
    imgView.layer.cornerRadius = 4.0
    imgView.clipsToBounds = true
    return imgView
}()

let label: UILabel = {
   let label = UILabel()
    label.text = "SOME DUMMY TEXT"
    label.font = UIFont.systemFont(ofSize: 16)
    label.numberOfLines = 0
    label.minimumScaleFactor = 0.9

    return label
}()

lazy var verticalStackView: UIStackView = {
   let stackView = UIStackView(arrangedSubviews: [self.imageView, self.label])
    stackView.axis = .vertical
    stackView.distribution = .fill
    stackView.spacing = 2.0
    return stackView
}()


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

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


func handleConstraints() {

    verticalStackView.translatesAutoresizingMaskIntoConstraints = false
    self.addSubview(verticalStackView)

    verticalStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
    verticalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    verticalStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
    verticalStackView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
}

我正在使用一种不同的语法来创建约束,因为我认为这一点更加清晰。您可以轻松地将其转换为所需的语法。

答案 1 :(得分:0)

可能是因为您将requiresConstraintBasedLayout设置为false,从而在您仍然尝试使用约束时会自动停用布局系统。