최근에 애니메이션에 관심이 많아져서 계속 애니메이션 관련글만 올리고있네요 ㅎㅎ
오늘 구현해볼 애니메이션이에요
대표적으로 음악앱을보면 앨범을 띄울때 이런 방식으로 띄우는걸 볼수있어요
이런 효과를 Carousel이라고 불러요
사전정의에는 '회전목마' 라고 하네요
이 애니메이션을 포함해서 다양한 Carousel효과가 많더라구요
처음이기때문에
자료를 찾아보면서 이것저것 해봤는데
좋은 코드가 있거나 방법이있다면
댓글달아주세요 😁
시작해볼까요..!
class ViewController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! let cellSize = CGSize(width: 200, height: 500) var minItemSpacing: CGFloat = 20 let cellCount = 8 var previousIndex = 0 override func viewDidLoad() { super.viewDidLoad() setupCollectionView() } func setupCollectionView() { collectionView.contentInsetAdjustmentBehavior = .never let cellWidth: CGFloat = floor(cellSize.width) let insetX = (view.bounds.width - cellWidth) / 2.0 collectionView.contentInset = UIEdgeInsets(top: 0, left: insetX, bottom: 0, right: insetX) collectionView.decelerationRate = .fast collectionView.delegate = self collectionView.dataSource = self } }
contentInsetAdjustmentBehavior
safe area때문에 가려지는 것을 방지하기위해서 자동으로 Inset을 조정해주는 역할을해요
때문에 스크롤뷰나, 컬랙션뷰등 스크롤있는 컴포넌트를 건들때 위의 공간이 남는 이유가 되기도하죠
FlowlayoutDelegate를 활용하거나
collectionView의 flowlayout을 변수로 가져올 수 있는데
이 둘을 섞어쓰면 변수값이 이상해지더라구요
아무튼 하나만 사용하세요..!
저는 전자를 택햇어요
collectionView의 item이 처음에 중앙에 와야 이쁘겟죠??
그래서 contentInset 작업을 해주고!!
뭐 빠르게 스크롤하겟다...delegate..datasource.. 기본적인걸 설정해줬어요
extension ViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return minItemSpacing } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return cellSize } // MARK: Paging Effect func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { let cellWidthIncludeSpacing = cellSize.width + minItemSpacing var offset = targetContentOffset.pointee let index = (offset.x + scrollView.contentInset.left) / cellWidthIncludeSpacing let roundedIndex: CGFloat = round(index) offset = CGPoint(x: roundedIndex * cellWidthIncludeSpacing - scrollView.contentInset.left, y: scrollView.contentInset.top) targetContentOffset.pointee = offset } }
다음으로는 아이템간격을 조절해주고
셀사이즈를 지정해주고
페이징 효과가 나도록 할거에요!!
스토리보드에 있는
isPagingEnabled
를 사용하게되면 한페이지의 넓이를 조절 할 수가없어요!!
크기가 같다면 상관이없지만 다르기때문에
scrollViewWillEndDragging
을 이용해서 코드로 구현할거에요
해당 아이템의 index를 offset을 이용해서 쉽게 구할수있지만
저희는 inset을 줫기때문에
contentInset만큼 꼭 더해줘야해요
pageIndex X Cell한칸(spacing+cellWidth) - inset을 하면
한페이지의 넓이만큼 딱 움직이겟죠??
여기까지 구현했다면
단순한 가운데정렬 페이징을 하는 효과를 볼 수 있어요
// MARK: Carousel Effect func scrollViewDidScroll(_ scrollView: UIScrollView) { let cellWidthIncludeSpacing = cellSize.width + minItemSpacing let offsetX = collectionView.contentOffset.x let index = (offsetX + collectionView.contentInset.left) / cellWidthIncludeSpacing let roundedIndex = round(index) let indexPath = IndexPath(item: Int(roundedIndex), section: 0) if let cell = collectionView.cellForItem(at: indexPath) { animateZoomforCell(zoomCell: cell) } if Int(roundedIndex) != previousIndex { let preIndexPath = IndexPath(item: previousIndex, section: 0) if let preCell = collectionView.cellForItem(at: preIndexPath) { animateZoomforCellremove(zoomCell: preCell) } previousIndex = indexPath.item } }
이제 Cell이 포커스되면 커지는 효과를 줘보려고해요
offset을 이용해서 현재 보여지는 index를 찾고
그 index에 있는 cell을 커지게
전의 cell은 원래 상태로 되돌리는 방식으로 구현해봤어요
func animateZoomforCell(zoomCell: UICollectionViewCell) { UIView.animate( withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: { zoomCell.transform = .identity }, completion: nil) } func animateZoomforCellremove(zoomCell: UICollectionViewCell) { UIView.animate( withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: { zoomCell.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) }, completion: nil) }
초기상태 scale 0.5 -> identity로 커지는 효과
애니메이션은 간단하죠 ㅎㅎ
여기까지 하셨다면 처음에 봤던 애니메이션을 볼 수 있을거에요
구현하긴 어려운데 하고나면 너무 이쁜게 매력인거 같아요
'iyOmSd > Title: Swift' 카테고리의 다른 글
[Swift] - JavaScriptCore(1/2) (0) | 2020.05.16 |
---|---|
[Swift] - TableView Header 및 Swipe Delete Action (2) | 2020.05.12 |
[Swift] - TabBar 애니메이션: CollectionView를 이용한 페이징 (2) | 2020.04.29 |
[Swift] - 화면전환 애니메이션 커스텀: UIViewControllerAnimatedTransitioning (4) | 2020.04.25 |
[Swift] - Apple Login (2/2) (0) | 2020.04.14 |