Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- Array vs Linked List
- 강한 참조 순환
- 면접을 위한 CS전공 지식 노트
- SWIFT
- NavigationSearchBar
- 자료구조
- 테이블뷰 나누기
- UserDefaults
- Reference Cycle
- Input Output
- Value Type Reference Type
- 롤케이크 자르기
- 프로그래머스
- wil
- firebase
- tableview section별 다른 cell적용
- UIKit
- @escaping
- coremotion
- TableView Section
- retain cycle
- 양궁대회
- Carousel CollectionView
- ReferceCycle
- til
- CarouselCollectionview
- TableView
- 면접을 위한 CS 전공 지식 노트 Tree
- class struct
- CoreData
Archives
- Today
- Total
개발하는 동글 :]
[TIL],[UIKit],[TRY],[CarouselCollectionview] 본문
1. 구현 영상
2. 구현
1. 사용할 이미지 배열, imageView, collectionView 생성
var imageDatas = [
UIImage(named: "image1"),
UIImage(named: "image2"),
UIImage(named: "image3"),
UIImage(named: "image4"),
UIImage(named: "image5"),
UIImage(named: "image6"),
UIImage(named: "image7")
]
var imageView = UIImageView()
let myCollectionView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
flowLayout.scrollDirection = .horizontal
return collectionView
}()
let cellSize = CGSize(width: 100, height: 100)
var minItemSpacing: CGFloat = 40
var previousIndex = 0
2. 사용할 Cell 생성
import UIKit
import SnapKit
class MyCollectionViewCell: UICollectionViewCell {
static let identifier = "MyCollectionViewCell"
let imageView = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
setUp()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setUp(){
self.addSubview(imageView)
imageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
3. setUp
func setUp(){
view.addSubview(imageView)
imageView.snp.makeConstraints { make in
make.edges.equalTo(view.safeAreaLayoutGuide)
}
view.addSubview(myCollectionView)
myCollectionView.showsHorizontalScrollIndicator = false
myCollectionView.contentInsetAdjustmentBehavior = .never
let cellWidth: CGFloat = floor(cellSize.width)
let insetX = (view.bounds.width - cellWidth) / 2.0
myCollectionView.contentInset = UIEdgeInsets(top: 0, left: insetX, bottom: 0, right: insetX)
myCollectionView.backgroundColor = .clear
myCollectionView.decelerationRate = .fast
myCollectionView.delegate = self
myCollectionView.dataSource = self
myCollectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: MyCollectionViewCell.identifier)
myCollectionView.snp.makeConstraints { make in
make.left.right.equalTo(view.safeAreaLayoutGuide)
make.height.equalTo(200)
make.centerY.equalTo(view.safeAreaLayoutGuide.snp.centerY)
}
}
4. CellSizeAnimation
func animateZoomforCell(zoomCell: UICollectionViewCell) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .curveEaseOut,
animations: {
zoomCell.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
},
completion: nil)
}
func animateZoomforCellremove(zoomCell: UICollectionViewCell) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .curveEaseOut,
animations: {
zoomCell.transform = .identity
},
completion: nil)
}
5. UICollectionViewDataSource
extension ViewController: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
imageDatas.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = self.myCollectionView.dequeueReusableCell(withReuseIdentifier: MyCollectionViewCell.identifier, for: indexPath) as? MyCollectionViewCell else {
return UICollectionViewCell()
}
cell.imageView.image = imageDatas[indexPath.row]
return cell
}
}
6. UICollectionViewDelegateFlowLayout, UICollectionViewDelegate
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
imageView.image = imageDatas[Int(roundedIndex)]
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let cellWidthIncludeSpacing = cellSize.width + minItemSpacing
let offsetX = myCollectionView.contentOffset.x
let index = (offsetX + myCollectionView.contentInset.left) / cellWidthIncludeSpacing
let roundedIndex = round(index)
let indexPath = IndexPath(item: Int(roundedIndex), section: 0)
//화면 로드시 첫 번째 Cell 대응
DispatchQueue.main.async { [weak self] in
guard let self = self else {return}
guard let cell = myCollectionView.cellForItem(at: indexPath) else { print("fail");return }
animateZoomforCell(zoomCell: cell)
imageView.image = imageDatas[Int(roundedIndex)]
}
//=========================================================================
if Int(roundedIndex) != previousIndex {
let preIndexPath = IndexPath(item: previousIndex, section: 0)
if let preCell = myCollectionView.cellForItem(at: preIndexPath) {
animateZoomforCellremove(zoomCell: preCell)
}
previousIndex = indexPath.item
}
}
}
3. 전체 코드
import UIKit
import SnapKit
class ViewController: UIViewController {
var imageDatas = [
UIImage(named: "image1"),
UIImage(named: "image2"),
UIImage(named: "image3"),
UIImage(named: "image4"),
UIImage(named: "image5"),
UIImage(named: "image6"),
UIImage(named: "image7")
]
var imageView = UIImageView()
let myCollectionView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
flowLayout.scrollDirection = .horizontal
return collectionView
}()
let cellSize = CGSize(width: 100, height: 100)
var minItemSpacing: CGFloat = 40
var previousIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
// self.view.backgroundColor = .green
setUp()
}
func setUp(){
view.addSubview(imageView)
imageView.snp.makeConstraints { make in
make.edges.equalTo(view.safeAreaLayoutGuide)
}
view.addSubview(myCollectionView)
myCollectionView.showsHorizontalScrollIndicator = false
myCollectionView.contentInsetAdjustmentBehavior = .never
let cellWidth: CGFloat = floor(cellSize.width)
let insetX = (view.bounds.width - cellWidth) / 2.0
myCollectionView.contentInset = UIEdgeInsets(top: 0, left: insetX, bottom: 0, right: insetX)
myCollectionView.backgroundColor = .clear
myCollectionView.decelerationRate = .fast
myCollectionView.delegate = self
myCollectionView.dataSource = self
myCollectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: MyCollectionViewCell.identifier)
myCollectionView.snp.makeConstraints { make in
make.left.right.equalTo(view.safeAreaLayoutGuide)
make.height.equalTo(200)
make.centerY.equalTo(view.safeAreaLayoutGuide.snp.centerY)
}
}
func animateZoomforCell(zoomCell: UICollectionViewCell) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .curveEaseOut,
animations: {
zoomCell.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
},
completion: nil)
}
func animateZoomforCellremove(zoomCell: UICollectionViewCell) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .curveEaseOut,
animations: {
zoomCell.transform = .identity
},
completion: nil)
}
}
extension ViewController: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
imageDatas.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = self.myCollectionView.dequeueReusableCell(withReuseIdentifier: MyCollectionViewCell.identifier, for: indexPath) as? MyCollectionViewCell else {
return UICollectionViewCell()
}
cell.imageView.image = imageDatas[indexPath.row]
return cell
}
}
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
imageView.image = imageDatas[Int(roundedIndex)]
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let cellWidthIncludeSpacing = cellSize.width + minItemSpacing
let offsetX = myCollectionView.contentOffset.x
let index = (offsetX + myCollectionView.contentInset.left) / cellWidthIncludeSpacing
let roundedIndex = round(index)
let indexPath = IndexPath(item: Int(roundedIndex), section: 0)
DispatchQueue.main.async { [weak self] in
guard let self = self else {return}
guard let cell = myCollectionView.cellForItem(at: indexPath) else { print("fail");return }
animateZoomforCell(zoomCell: cell)
imageView.image = imageDatas[Int(roundedIndex)]
}
if Int(roundedIndex) != previousIndex {
let preIndexPath = IndexPath(item: previousIndex, section: 0)
if let preCell = myCollectionView.cellForItem(at: preIndexPath) {
animateZoomforCellremove(zoomCell: preCell)
}
previousIndex = indexPath.item
}
}
}