Daniel Dramond Daniel Dramond - 1 month ago 29
Swift Question

Swift 3: How to animate when swiping through collection view

I have a collectionView inside of a ViewController. When I swipe, it swipes to another Collection View Cell which is the height and width of the view.frame

I want to have an animation that starts whenever I start swiping, to then finish whenever the collection view locks into the centre of a cell just like the gif below. I don't have a label or textview in my code but could you point me in the right direction on how I would do this? Here's my relevent code:

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .white
cv.dataSource = self
cv.delegate = self
cv.isPagingEnabled = true
cv.showsHorizontalScrollIndicator = false
return cv
}()

let cellId = "cellId"
let loginCellId = "loginCellId"

let pages: [Page] = {
let firstPage = Page(imageName: "introduction_1")
let secondPage = Page(imageName: "introduction_2")
let thirdPage = Page(imageName: "introduction_3")
let fourthPage = Page(imageName: "introduction_4")
return [firstPage, secondPage, thirdPage, fourthPage]
}()

lazy var pageControl: UIPageControl = {
let pc = UIPageControl()
pc.pageIndicatorTintColor = .lightGray
pc.currentPageIndicatorTintColor = .darkGray
pc.numberOfPages = self.pages.count + 1
return pc
}()

override func viewDidLoad() {
super.viewDidLoad()

view.addSubview(collectionView)
view.addSubview(pageControl)

_ = pageControl.anchor(nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 40)

collectionView.anchorToTop(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)

registerCells()
}

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

let pageNumber = Int(targetContentOffset.pointee.x / view.frame.width)
pageControl.currentPage = pageNumber
}

fileprivate func registerCells() {
collectionView.register(PageCell.self, forCellWithReuseIdentifier: cellId)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: loginCellId)

}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count + 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

if indexPath.item == pages.count {
let loginCell = collectionView.dequeueReusableCell(withReuseIdentifier: loginCellId, for: indexPath)
return loginCell
}

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! PageCell

let page = pages[indexPath.item]
cell.page = page

return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height)
}


}

class PageCell: UICollectionViewCell {

var page: Page? {
didSet {
guard let page = page else {
return
}
imageView.image = UIImage(named: page.imageName)
}
}

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

setupViews()
}

let imageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.backgroundColor = .yellow
iv.clipsToBounds = true
return iv
}()

func setupViews() {

addSubview(imageView)

imageView.anchorToTop(topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor)
}

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


}

enter image description here

Answer

From my standpoint, in your case it is better to use UIPageViewController instead of UICollectionView. It has a whole bunch of features for you to implement the UI you've shown above. There is a good tutorial on this topic - https://www.veasoftware.com/posts/uipageviewcontroller-in-swift-xcode-62-ios-82-tutorial?rq=page