渐变层覆盖集合视图中的所有项目,不考虑间距

Gradient Layer covers all items in Collection View with no respect of spacing

所以我使用了一个名为 Scaling Carousel 的第三方库,大部分情况下它都非常好,但出于某种原因,当我尝试自定义它并向其添加渐变图层甚至添加阴影时没有贴好?我在下面附上了一张图片以供参考。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

        var view = UILabel()

        view.frame = CGRect(x: 0, y: 0, width: 236, height: 130)

        let layer0 = CAGradientLayer()

               layer0.colors = [

                 UIColor(red: 1, green: 0.46, blue: 0.467, alpha: 1).cgColor,

                 UIColor(red: 1, green: 0.36, blue: 0.369, alpha: 1).cgColor

               ]

               layer0.locations = [0, 1]

               layer0.startPoint = CGPoint(x: 0.25, y: 0.5)

               layer0.endPoint = CGPoint(x: 0.75, y: 0.5)

               layer0.transform = CATransform3DMakeAffineTransform(CGAffineTransform(a: -1, b: 1, c: -1, d: -2.48, tx: 1.5, ty: 1.24))

        layer0.bounds = view.bounds.insetBy(dx: -0.5*view.bounds.size.width, dy: -0.5*view.bounds.size.height)

        layer0.position = view.center


        view.layer.addSublayer(layer0)

        cell.addSubview(view)


        if let scalingCell = cell as? ScalingCarouselCell {
            scalingCell.mainView.backgroundColor = .white

        }

这是缩放轮播代码

open class ScalingCarouselCell: UICollectionViewCell {

    // MARK: - Properties (Public)

    /// The minimum value to scale to, should be set between 0 and 1
    open var scaleMinimum: CGFloat = 0.9

    /// Divisior used when calculating the scale value.
    /// Lower values cause a greater difference in scale between subsequent cells.
    open var scaleDivisor: CGFloat = 10.0

    /// The minimum value to alpha to, should be set between 0 and 1
    open var alphaMinimum: CGFloat = 0.85

    // MARK: - IBOutlets

    // This property should be connected to the main cell subview
    @IBOutlet public var mainView: UIView!

    // MARK: - Overrides

    override open func layoutSubviews() {
        super.layoutSubviews()

        guard let carouselView = superview as? ScalingCarouselView else { return }

        scale(withCarouselInset: carouselView.inset)
    }

    override open func prepareForReuse() {
        super.prepareForReuse()
        mainView.transform = CGAffineTransform.identity
        mainView.alpha = 1.0

    }


    /// Scale the cell when it is scrolled
    ///
    /// - parameter carouselInset: The inset of the related SPBCarousel view
    open func scale(withCarouselInset carouselInset: CGFloat) {

        // Ensure we have a superView, and mainView
        guard let superview = superview,
            let mainView = mainView else { return }

        // Get our absolute origin value
        let originX = superview.convert(frame, to: superview.superview).origin.x

        // Calculate our actual origin.x value using our inset
        let originXActual = originX - carouselInset

        let width = frame.size.width

        // Calculate our scale values
        let scaleCalculator = abs(width - abs(originXActual))
        let percentageScale = (scaleCalculator/width)

        //Calculate distance between our carousel views
        let scaleValue = scaleMinimum
        //Add the following line for a greater carousel effect.
        //+ (percentageScale/scaleDivisor)

        let alphaValue = alphaMinimum
            + (percentageScale/scaleDivisor)

        let affineIdentity = CGAffineTransform.identity

        // Scale our mainView and set it's alpha value
        mainView.transform = affineIdentity.scaledBy(x: scaleValue, y: scaleValue)
        mainView.alpha = 1.0

        // ..also..round the corners
        mainView.layer.cornerRadius = 28

我的建议是使用一个 UIView subclass,其中包含渐变和圆角半径逻辑。

因此,首先,将此代码添加到您的项目中:

@IBDesignable
class KFGradientView: UIView {

    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }

    private var gLayer: CAGradientLayer {
        return self.layer as! CAGradientLayer
    }

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

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() {
        gLayer.type = .axial

        gLayer.colors = [
            UIColor(red: 1, green: 0.46, blue: 0.467, alpha: 1).cgColor,
            UIColor(red: 1, green: 0.36, blue: 0.369, alpha: 1).cgColor
        ]
        gLayer.locations = [0, 1]
        gLayer.startPoint = CGPoint(x: 0.25, y: 0.5)
        gLayer.endPoint = CGPoint(x: 0.75, y: 0.5)

        // exaggerated colors so it's obvious
        // remove or comment-out this to use original red-ish colors
        gLayer.colors = [
            UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1).cgColor,
            UIColor(red: 1.0, green: 1.0, blue: 0.0, alpha: 1).cgColor
        ]

        gLayer.cornerRadius = 28
    }

}

接下来,为了进行快速测试,将视图控制器添加到故事板并添加 UIView 子视图。将该视图的 class 更改为 KFGradientView(忽略 scratchy -- 你应该在那里看到你的项目名称):

在顶部菜单栏中,select Editor -> Refresh All Views(或选中 Automatically Refresh Views)。你应该看到这个:

假设您这样做,请转到您的 Collection View Cell 原型,并将 mainView 的 class 从 UIView 更改为 KFGradientView。你应该看到同样的事情发生在那里。

然后,从 class ScalingCarouselCell: UICollectionViewCell 中的 func scale(...) 中删除这一行:

mainView.layer.cornerRadius = 28

并将您的 cellForItemAt 函数更改为:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ScalingCarouselCell

    return cell
}

至于您的 mainView 没有正确调整大小/在单元格中的位置,那么,这是一个完全不同的问题。如果你不明白,post 那是一个新问题。