I want to achieve the effect like this: I click cell and the button's alpha become to 0, then enlarge the cell and move to center of Screen.
And Here is my code and gif:
**// This is my VC**
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private lazy var collectionView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .vertical
flowLayout.itemSize = CGSize(width: 152, height: 212)
flowLayout.sectionInset = UIEdgeInsets(top: 12, left: 16, bottom: 12, right: 16)
flowLayout.minimumLineSpacing = 24
flowLayout.minimumInteritemSpacing = 16
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
collectionView.register(ListViewControllerCell.self, forCellWithReuseIdentifier: "ListCell")
collectionView.dataSource = self
collectionView.delegate = self
collectionView.decelerationRate = .fast
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.clipsToBounds = false
collectionView.alwaysBounceVertical = true
return collectionView
}()
}
extension ViewController {
private func setupUI() {
view.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ListCell", for: indexPath)
return cell
}
}
class ListViewControllerCell: UICollectionViewCell {
static let identifier = "ListCell"
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
}
private lazy var pannelView: UIView = {
let view = UIView()
view.layer.cornerRadius = 8
view.backgroundColor = .yellow
return view
}()
private lazy var clickButton: UIButton = {
let button = UIButton()
button.layer.cornerRadius = 11
button.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
button.setTitle("Click Me!!", for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.backgroundColor = .white
button.addTarget(self, action: #selector(onClickButton), for: .touchUpInside)
return button
}()
private func setupUI() {
contentView.addSubview(pannelView)
contentView.addSubview(clickButton)
pannelView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
clickButton.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().inset(16)
make.height.equalTo(22)
}
}
}
extension ListViewControllerCell {
@objc private func onClickButton() {
// 1: set button alpha to 0.
let buttonOpacity = CABasicAnimation(keyPath: "opacity")
buttonOpacity.toValue = 1
buttonOpacity.fromValue = 0
buttonOpacity.duration = 0.4
buttonOpacity.fillMode = .forwards
buttonOpacity.isRemovedOnCompletion = false
// 2: enlarge cell and set it position to center.
let cellEnlargeTransition = CABasicAnimation(keyPath: "transform.scale")
cellEnlargeTransition.fromValue = 1
cellEnlargeTransition.toValue = 2
cellEnlargeTransition.beginTime = CACurrentMediaTime() + 0.4
cellEnlargeTransition.duration = 1
cellEnlargeTransition.fillMode = .forwards
cellEnlargeTransition.isRemovedOnCompletion = false
let cellEnlargePosition = CAKeyframeAnimation(keyPath: "position")
let path = CGMutablePath()
path.move(to: CGPoint(x: contentView.frame.minX, y: contentView.frame.minY))
let toPositonX = (screenWidth - contentView.bounds.width)/2
let toPositionY = (screenWidth - contentView.bounds.height)/2
path.addLine(to: CGPoint(x: toPositonX, y: toPositionY))
cellEnlargePosition.path = path
cellEnlargePosition.beginTime = CACurrentMediaTime() + 0.4
cellEnlargeTransition.duration = 1
cellEnlargeTransition.fillMode = .forwards
cellEnlargePosition.isRemovedOnCompletion = false
CATransaction.begin()
clickButton.layer.add(buttonOpacity, forKey: nil)
contentView.layer.add(cellEnlargeTransition, forKey: nil)
contentView.layer.add(cellEnlargePosition, forKey: nil)
CATransaction.commit()
}
}
I have couple of questions:
1.
The beginning position is not right, the transition animation should start at cell's originX and originY.
2.
I want to keep button's alpha to zero, but it comes to 1 again when the "opacity" animation is over.
3.
The ending position is also not right, I want to keep it at center of the screen.
4.
I want the cell hierarchy to be higher than the others which do not execute animation.