Я пытался реализовать горизонтальную UIPickerView
с анимацией для уменьшения и увеличения размера метки во время прокрутки, контролируя их положение, если в центре, и поэтому в выбранной, сделать ее больше другой, как то так
То, что я разработал, хорошо, но у меня есть только одна проблема, все метки меняются одновременно, я хочу анимацию, которая меняет метку во время прокрутки в основании позиции, теперь мой сборщик похож на это
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()
}
}
Дайте мне знать, знаете ли вы какой-нибудь какао, чтобы сделать это, или, может быть, вы можете помочь мне с трюком, которого я до сих пор не знаю:)