Горизонтальный UIPickerView с анимацией - PullRequest
0 голосов
/ 07 января 2019

Я пытался реализовать горизонтальную UIPickerView с анимацией для уменьшения и увеличения размера метки во время прокрутки, контролируя их положение, если в центре, и поэтому в выбранной, сделать ее больше другой, как то так

enter image description here

То, что я разработал, хорошо, но у меня есть только одна проблема, все метки меняются одновременно, я хочу анимацию, которая меняет метку во время прокрутки в основании позиции, теперь мой сборщик похож на это

https://gph.is/2VCtupV

Если вы видите, что все ярлыки меняются одновременно, я хотел бы больше походить на смену выпускного, возможно, согласовать со свитком, у кого-нибудь есть идеи ?! Здесь я выкладываю код, который использовал для всего:

CollectionCell код

import UIKit

class CalendarCollectionViewCell: UICollectionViewCell {

    var dayLabel: UILabel!

    var font = UIFont.systemFont(ofSize: 40)

    override var isSelected: Bool {
        didSet {
            let animation = CATransition()
            animation.type = .fade
            animation.duration = 0.15
            dayLabel.layer.add(animation, forKey: "")
            dayLabel.font = font
        }
    }

    var distanceFromCenter: CGFloat = 0 {
        didSet {
            let animation = CATransition()
            animation.type = .fade
            animation.duration = 0.15
            dayLabel.layer.add(animation, forKey: "")
            let percentage = font.pointSize - (distanceFromCenter * 10)
            dayLabel.font = distanceFromCenter != 0 ? UIFont.systemFont(ofSize: percentage) : font
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        isUserInteractionEnabled = false
        initialize()
    }

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

    override func prepareForReuse() {
        dayLabel.text = nil
    }

    func initialize() {
        layer.isDoubleSided = false
        layer.shouldRasterize = true
        layer.rasterizationScale = UIScreen.main.scale

        dayLabel = UILabel(frame: contentView.bounds)
        dayLabel.backgroundColor = .clear
        dayLabel.textAlignment = .center
        dayLabel.textColor = .black
        dayLabel.numberOfLines = 1
        dayLabel.lineBreakMode = .byTruncatingTail
        dayLabel.highlightedTextColor = .black
        dayLabel.font = font
        dayLabel.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleBottomMargin, .flexibleRightMargin]
        contentView.addSubview(dayLabel)
    }

}

CollectionView код

import UIKit

class CalendarModelPicker: UICollectionView {

    var dateModel: [Int]!

    var currentIndex: Int = 0

    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
        super.init(frame: frame, collectionViewLayout: layout)
        register(CalendarCollectionViewCell.self, forCellWithReuseIdentifier: "dateCell")
        delegate = self
        dataSource = self
        backgroundColor = .white
    }

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


extension CalendarModelPicker: UICollectionViewDelegate {

}

extension CalendarModelPicker: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dateModel.count
    }

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

         let day = String(dateModel[indexPath.row])
         cell.dayLabel.text = day

         return cell
    }

}

extension CalendarModelPicker: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if let cell = cellForItem(at: indexPath) as? CalendarCollectionViewCell {
            cell.distanceFromCenter = CGFloat(abs(indexPath.item - currentIndex))
        }
        return CGSize(width: 50, height: 50)
    }
}

extension CalendarModelPicker: UIScrollViewDelegate {
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let layout = collectionViewLayout as! UICollectionViewFlowLayout
        let cellWidthIncludingSpacing = layout.itemSize.width + layout.minimumLineSpacing
        var offset = targetContentOffset.pointee
        let index = (offset.x + scrollView.contentInset.left) / cellWidthIncludingSpacing
        let roundedIndex = round(index)
        offset = CGPoint(x: roundedIndex * cellWidthIncludingSpacing - scrollView.contentInset.left, y: -scrollView.contentInset.top)
        targetContentOffset.pointee = offset
    }


    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        var visibleRect = CGRect()

        visibleRect.origin = contentOffset
        visibleRect.size = bounds.size

        let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)

        guard let indexPath = indexPathForItem(at: visiblePoint) else { return }

        currentIndex = indexPath.row
        collectionViewLayout.invalidateLayout()
    }
}

Дайте мне знать, знаете ли вы какой-нибудь какао, чтобы сделать это, или, может быть, вы можете помочь мне с трюком, которого я до сих пор не знаю:)

...