通过 AutoLayout 构建等比缩放当 UIImageView

发布
更新
字数 247
阅读 2 分钟
阅读量 985

思路比较简单,当设置图片时,通过计算高宽比,重置相应的 NSLayoutConstraint 来实现,而重置是在高宽比didSet 中完成的。

class ImageCell: UICollectionViewCell {
    static let reuseIdentifier = "image cell"
    
    // Cache the image view height constraint
    private var imageViewHeightConstraint: NSLayoutConstraint?
    
    /// Setup the imageview in the cell for demo
    private lazy var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.clipsToBounds = true
        imageView.contentMode = .scaleAspectFill
        imageView.layer.borderColor = UIColor.red.cgColor
        imageView.layer.borderWidth = 2
        imageView.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(imageView)
        
        let margins = contentView.layoutMarginsGuide
        
        let heightConstraint = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: multiplier)
        heightConstraint.priority = UILayoutPriority(rawValue: 999)
        self.imageViewHeightConstraint = heightConstraint
        
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: margins.topAnchor),
            imageView.trailingAnchor.constraint(equalTo: margins.trailingAnchor),
            imageView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
            height,
            imageView.bottomAnchor.constraint(equalTo: margins.bottomAnchor),
        ])
        
        return imageView
    }()
    
    private var multiplier: CGFloat = 1 {
        didSet {
            guard oldValue != multiplier else { return }
            // 3. invalid the previous height constraint
            if let constraint = imageViewHeightConstraint {
                imageView.removeConstraint(constraint)
            }
            // 4. setup the new height constraint
            let heightConstraint = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: multiplier)
            // in addition, set the priority to avoid autolayout issue
            heightConstraint.priority = UILayoutPriority(rawValue: 999)
            // 5. active the new height constraint
            heightConstraint.isActive = true
            // 6. cache it, done
            imageViewHeightConstraint = heightConstraint
        }
    }
    
    func setImage(_ image: UIImage) {
        // 1. set the `imageView.image`
        imageView.image = image
        // 2. calculate the height multiple width ratio
        multiplier = image.size.height / image.size.width
    }
}