스닥
Playground
스닥
전체 방문자
오늘
어제
  • 분류 전체보기 (125)
    • 개발자 기본기 (1)
    • Swift 아키텍처 (6)
    • iOS 개발 (55)
      • Swift (12)
      • UIKit (17)
      • SwiftUI (9)
      • CoreData (9)
      • MusicKit (4)
      • WebKit (2)
      • 개발 환경 (0)
      • WatchOS (2)
    • 애플 개발자 아카데미 (4)
    • 막 쓰는 개발일지 (0)
    • 운영체제 (4)
    • 네트워크, 서버 (16)
      • Network (9)
      • Server (7)
    • 알고리즘 (8)
    • C언어 (7)
      • 함수 (7)
    • 하루 이야기 (23)

블로그 메뉴

  • GitHub계정
  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 서버
  • 문자열 복사
  • 도커
  • BFS
  • 알고리즘
  • C 언어
  • Server
  • Core Animation
  • 너비 우선
  • ip주소
  • SWIFT
  • ios rendering
  • 자료구조
  • 트리
  • 깊이 우선
  • struct class 성능
  • swift performance
  • docker
  • core data
  • dfs

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
스닥

Playground

[UICollectionView] View를 하나씩 넘기기, 여러개씩 넘기기
iOS 개발/UIKit

[UICollectionView] View를 하나씩 넘기기, 여러개씩 넘기기

2021. 11. 17. 20:32

 

 

 

우리가 보는 많은 앱들에는 CollectionView가 생각보다 핵심적인 기능으로 들어가는 경우가 많습니다.

 

Netfilx 앱에서 옆으로 밀어서 영화를 탐색할 때, coupang에서 찜한 목록 등을 볼 때 등 

컬렉션 뷰는 테이블 뷰가 하는 일을 모두 할 수 있으면서도 레이아웃까지 가지고 있어서 수직 스크롤 뿐만 아니라 수평 스크롤도 가능합니다.

 

 

하지만 아래 앱처럼, 하나씩 넘기는 건 어떻게 구현할 수 있을까요??

하나씩 넘기고, 현재 내가 보고 있는 collectionView의 index가 어떤 인덱스인지까지 확인하는 방법은 무엇일까요?

 

 

 

 

 

 

일단 주우우우욱 스크롤이 되는 collectionView는 만들 수 있을 겁니다.

tableView를 만들 수 있다면, 분명히 쉽게 가능할 것입니다.

 

 

하지만 지금 내가 어떤 뷰를 보고 있고, 한장씩만 뷰가 넘어가게 하는 방법을 구현하기 위해서는 

 

 

 

UIScrollViewDelegate에서 이 함수를 알아야 합니다.

 

먼저 tableView와 CollectionView 모두 scroll 기능을 가지고 있기 때문에, 당연히 UIScrollViewDelegate를 채택해서 scroll에 대한 기능을 우리 임의대로 구현해줄 수 있습니다.

 

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

 

 

 

이 함수는 무엇일까요??

 

함수 이름인 scrollViewWillEndDragging에서 알 수 있듯이

 

이 함수는 우리의 드래그가 끝나는 지점을 인식합니다.

 

 

즉 우리가 드래그를 하다가 손이 딱 떨어지는 지점을 인식하는거에요!!

그 떄, 이 함수가 실행이 됩니다!ㅎㅎㅎ

 

 

 

 

자! 그럼 이 함수를 어떻게 수정해주어야 할까요??

 

 

 

 

짜잔!! 갓 STACKOVERFLOW느님...ㅎㅎㅎㅎㅎㅎ

 

var currentIndex = 0

extension MainViewController: UIScrollViewDelegate {

    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let layout = self.canvasCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
        let cellWidthIncludingSpacing = layout.itemSize.width + layout.minimumLineSpacing
        var offset = targetContentOffset.pointee
        let index = (offset.x + scrollView.contentInset.left) / cellWidthIncludingSpacing
        var roundedIndex = round(index)
        
        if scrollView.contentOffset.x > targetContentOffset.pointee.x {
            roundedIndex = floor(index)
        } else if scrollView.contentOffset.x < targetContentOffset.pointee.x {
            roundedIndex = ceil(index)
        } else {
            roundedIndex = round(index)
        }

        if isOneStepPaging && (currentIndex != roundedIndex) {
            let num: CGFloat = currentIndex > roundedIndex ?  -1.0 : 1.0
            
            // 부수적 처리들. taptic feedback 혹은 상단 날짜 변경 등
        }
        offset = CGPoint(x: roundedIndex * cellWidthIncludingSpacing - scrollView.contentInset.left, y: -scrollView.contentInset.top)
        targetContentOffset.pointee = offset
    }
}

 

 

자 쉽지는 않아보이지만, 하나씩 뜯어가다 보면 답을 찾을 수 있습니다.

 

 

아까 우리의 손가락이 드래그를 하다가 화면에서 떨어질 때, 이 함수가 발동된다고 했죠??

 

 

 

여기서는 index 를 정하는 부분만 잘 보면 됩니다!!

 

 

 

간단한 그림을 한번 그려볼게요!!

 

자 여기서 눈여겨 봐야 할 변수는 TargetContentOffset입니다!

 

이 함수 자체에서 가져오는 것으로, 손가락이 떨어지는 시점에 이 collectionViewCell의 x지점 있죠??

 

origin X라고 생각하면 편할거에요!!

 

그 지점이 전체 길이의 절반을 넘어갔는지 안넘어갔는지만 체크하는거에요!!!

 

 

 

 

 

 

 

자 절반을 넘어갔으면, 반올림 처리를 했을 때 값이 올라가겠죠??

 

 

그리고 이제 좀 더 아랫줄을 보면, currentIndex랑 비교를 하잖아요?

currentIndex는 우리가 처음에 보고 있는 collectionViewCell의 index 이에요!!

 

 

 

currentIndex랑 반올림 처리된 index 값과 비교해서 index 값이 더 크면 currentIndex를 1 올려주고

그 반대의 경우는 -1 을 해주고!!

같으면 그냥 그대로 두고!!

 

쉽죠??

 

 

그래서 결국 새로 계산된 인덱스 값으로 다시 offset을 정해주는 작업을 요 마지막 부분에서 해주게 됩니다!!

 

offset = CGPoint(x: roundedIndex * cellWidthIncludingSpacing - scrollView.contentInset.left, y: -scrollView.contentInset.top)
targetContentOffset.pointee = offset

 

'iOS 개발 > UIKit' 카테고리의 다른 글

[UIView] 정말 예쁜 blur Effect  (0) 2021.11.21
[Swift] App 첫 로딩을 감지하는 법 (first loading detection)  (0) 2021.11.20
[Swift] 앱 안에서 메일 보내기  (0) 2021.11.20
[GestureRecognizer] Gesture 잘 사용하기 - 동시에 여러 gesture 사용하기, 주의점  (0) 2021.11.17
[UIImageView] image 색 변경하기  (0) 2021.11.09
[UITableVIew] automaticDimension 이 되지 않을때  (0) 2021.10.18
[UIView] view를 fade in, fade out 시키는 방법  (0) 2021.09.21
[Animation] animation play 중간에 값 변경하는 몇가지 방법  (0) 2021.09.21
    스닥
    스닥
    https://github.com/feldblume5263

    티스토리툴바