[Swift] CollectionVeiw로 ImagePager 만들기 (1)

민경준·2021년 11월 8일
1

사용 된 라이브러리

  1. snapKit
  2. UIKit
  3. Foundation

1. 기초단계

1-1. ViewController 설정하기

/// 실제 핸드폰 기종마다 다른
/// 위, 아래 SafeArea 높이를 구하기 위한 변수들
fileprivate var window: UIWindow?
fileprivate var topSafeAreaHeight: CGFloat {
    get {
        guard let window = self.window else { return 0 }
            
        return window.safeAreaLayoutGuide.layoutFrame.minY
    }
}
fileprivate var bottomSafeAreaHeight: CGFloat {
    get {
        guard let window = self.window else { return 0 }
            
        return window.frame.maxY - window.safeAreaLayoutGuide.layoutFrame.maxY
    }
}


/// 사진을 스크롤하기 위한 UICollectionView
fileprivate var collectionView: UICollectionView = {
    /// 스크롤은 가로방향으로 설정해준다. 
    let collectionViewLayout = UICollectionViewFlowLayout()
    collectionViewLayout.scrollDirection = .horizontal
    
    /// 추후에 Layout 설정으로 frame을 조절해주기 때문에
    /// 처음 값은 .zero 로 설정한다.
    let collectionView = UICollectionView(
        frame: .zero,
        collectionViewLayout: collectionViewLayout
    )
    
    /// contentInsetAdjustmentBehavior: 
    /// 자동으로 scrollView의 Inset을 조절해주는지의 여부를 묻는 값
    collectionView.showsVerticalScrollIndicator = false
    collectionView.showsHorizontalScrollIndicator = false
    collectionView.allowsMultipleSelection = false
    collectionView.isPagingEnabled = true
    collectionView.contentInsetAdjustmentBehavior = .never
        
    return collectionView
}()

override func viewDidLoad() {
    super.viewDidLoad()
        
    self.view.backgroundColor = .black
        
    self.setLayoutConstraints()
    self.setDelegates()
}

/// Layout 설정
func setLayoutConstraints() {
    /// CollectionView의 사이즈와 위치를
    /// VC의 View와 같도록 설정해준다.
    self.view.addSubview(self.collectionView)
    self.collectionView.snp.makeConstraints({
        $0.size.equalTo(self.view)
        $0.center.equalTo(self.view)
    })
}

/// Delegate 설정
func setDelegates() {
    self.collectionView.delegate = self
    self.collectionView.dataSource = self
    register(ImagePageCell.self, forCellWithReuseIdentifier: "ImagePageCell")  
}

1-2. Cell 설정하기

/// 이미지 확대 기능을 넣기위한 ScrollView
fileprivate let scrollView: UIScrollView = {
    let scrollView = UIScrollView()
    scrollView.showsVerticalScrollIndicator = false
    scrollView.showsHorizontalScrollIndicator = false
    
    /// 사진을 확대할 때 사용할 옵션
    /// 최대 사이즈, 최소 사이즈
    scrollView.maximumZoomScale = 4
    scrollView.minimumZoomScale = 1
}()

/// 각 Cell에 이미지를 담을 ImageView
fileprivate let imageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFit
    imageView.backgroundColor = .clear
    imageView.clipsToBounds = true
        
    return imageView
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    self.backgroundColor = .black
    
    /// ScrollView의 크기는 cell의 크기와 같도록 설정한다.
    self.contentView.addSubview(self.scrollView)
    self.scrollView.snp.makeConstraints({
        $0.size.equalTo(self.contentView)
        $0.top.right.left.bottom.equalTo(self.contentView)
    })
    
    /// ImageView는 ScrollView의 자식뷰로 추가한다.
    /// 크기는 ScrollView와 같도록 하고
    /// ScrollView의 ContentSize가 조절될 수 있도록
    /// ContentLayoutGuide에도 Layout 설정을 추가해준다.
    self.scrollView.addSubview(self.imageView)
    self.imageView.snp.makeConstraints({
        $0.size.equalTo(self.scrollView)
        $0.top.right.left.bottom.equalTo(self.scrollView.contentLayoutGuide)
    })
}

1-3. Delegate 설정하기

extension UIViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIGestureRecognizerDelegate {
    /// collectionView의 갯수를 지정해주는 dataSource 함수
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        /// image 갯수로 collectionView item 갯수를 정해준다.
        return self.images.count
    }
    /// collectionView cell에 대한 설정을 위한 dataSource 함수
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell: ImagePageCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImagePageCell", for: indexPath) as! ImagePageCell
        cell.image = self.images[indexPath.row]
        
        return cell
    }
    /// collectionView cell의 크기를 지정해주는 delegate 함수
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        var size = collectionView.frame.size
        
        /// 위, 아래 SafeArea의 높이를 뺀 크기로
        /// cell의 크기를 지정해준다.
        let bottomInset = self.bottomSafeAreaHeight
        let topInset = self.topSafeAreaHeight
        
        size.height = size.height - topInset - bottomInset
        
        return size
    }
    /// collectionView cell의 inset을 지정해주는 delegate 함수
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        /// cell의 위아래에 Inset을 줘서 cell이 중간에 위치하도록 한다.
        let bottomInset = Size.bottomSafeAreaHeight
        let topInset = Size.topSafeAreaHeight
        
        return UIEdgeInsets(top: topInset, left: 0, bottom: bottomInset, right: 0)
    }
    /// 섹션 사이의 크기를 지정해주는 delegate 함수
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
}

Result

이 정도만 코드를 작성해도 이미지 페이징은 가능하다.
하지만 이미지 페이징을 하는 이유는 확대하여 보기 위함이니
다음 챕터에서는 확대하는 제스처를 어떻게 다루는지 적어보도록 하겠다.

profile
iOS Developer 💻

0개의 댓글