Слой градиента охватывает все элементы в представлении коллекции без учета расстояния - PullRequest
0 голосов
/ 05 февраля 2020

Так что я использую стороннюю библиотеку под названием 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

without gradient code with gradient code

1 Ответ

1 голос
/ 05 февраля 2020

Я предлагаю использовать UIView подкласс с логинами градиента и радиуса угла c внутри.

Итак, сначала добавьте этот код в ваш проект:

@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. Измените класс этого представления на KFGradientView (игнорируйте scratchy - там вы увидите название вашего проекта):

enter image description here

В верхней строке меню выберите Editor -> Refresh All Views (или отметьте Automatically Refresh Views). Вы должны увидеть это:

enter image description here

Предполагая, что вы сделаете, go для вашего прототипа ячейки Collection View и измените класс mainView с UIView до KFGradientView. Там должно произойти то же самое.

Затем удалите эту строку из вашего func scale(...) в вашем class ScalingCarouselCell: UICollectionViewCell:

mainView.layer.cornerRadius = 28

и измените cellForItemAt fun c to:

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

    return cell
}

Если ваш mainView не будет правильно определен в ячейке, ну, это совсем другая проблема. Если вы не можете понять это, опубликуйте это как новый вопрос.

...