[UIScrollView] 상단 커스텀 탭바를 만들어봅시다! (2) - StickyHeader 기능 추가

2023. 12. 7. 14:29UIKit, H.I.G

728x90

1️⃣ 오늘 구현할 기능, StickyHeader란 무엇일까?


 

[UISegmentedControl] 상단 커스텀 탭바를 만들어봅시다! (1) - UISegmentedControl 활용

1️⃣ 오늘 만들어줄 화면은? 합동 세미나 과제로 테이블링 어플을 클론코딩하면서 만들었던 상단 커스텀 탭바의 내용을 정리해보겠다. 여러 글들을 찾아봤을 때, 상단 커스텀 탭바를 만들어주

mini-min-dev.tistory.com

오늘 글은 지난번 커스텀 탭바를 만들었던 내용에 이어서, 추가적으로 Sticky Header 기능을 구현해 준 내용으로 써보겠다.
(커스텀 탭바 기능에 대한 설명은 위에 첨부해놓은 지난 글로 넘어가서 읽고 오길 바란다.)

StickyHeader라는 말이 잘 와닿지 않아서 그렇지,
쉽게 설명하면 스크롤을 했을 때 "특정한 스크롤 지점부터는 상단에 헤더처럼 딱 달라붙는 화면"을 StickyHeader라고 부른다.

나는 지난번에 만들었던 커스텀 탭바 뷰를 아래 영상처럼 StickyHeader로 만들어보려고 했다.

 

 

2️⃣ StickyHeader 구현을 위한 기본 세팅


사실 이 화면은 일종의 "트릭"이 들어있는 화면이다.

어떤 트릭인고 하면,
사실 하나의 커스텀 탭바처럼 보였던 화면을 두개로 만들어 놓고 (스크롤뷰에 들어가 있는 탭바 하나. 스크롤 뷰 밖에 있는 탭바 하나.)

 

처음 화면에서는 스크롤 뷰 밖에 있는 탭바를 hidden 처리 해주다가,
일정한 스크롤 (여기서는 스크롤뷰 안에 있는 탭바가 스크롤이 되어 내가 붙이고 싶은 상단에 위치했을 때가 되겠다.)이 되었을 때 hidden 속성을 꺼서 보이게끔 만드는 처리를 해주는 것이다.

무슨 말인지 잘 이해가 안 되는가? 아래 코드로 살펴보면서 이해를 해보자.

뷰컨에는 스크롤 뷰 안에 포함될 normalCustomTabBarHeaderView고정되는 헤더로 보이게 될 stickyCustomTabBarHeaderView를 각각 선언하고, 알맞게 레이아웃(스크롤 뷰 속 헤더뷰는 뷰 계층에 맞게, 스크롤 밖 헤더뷰는 내가 고정하고 싶은 위치에 맞게)과 계층을 잡아주자.

아. 그리고 SticyHeaderView는 처음에는 isHidden = true 코드로 화면에서 보이지 않게 설정해줘야 할 것이다.

    private lazy var normalCustomTabBarHeaderView = storeDetailView.customTabBarHeaderView
    
    private let stickyCustomTabBarHeaderView = {
        let view = CustomTabBarHeaderView()
        view.backgroundColor = .TablingWhite
        view.isHidden = true
        return view
    }()

(1) view -> stickyheaderview, (2) view -> scrollview -> contentview -> storedetailview -> normalheaderview 계층을 비교

 

 

3️⃣ Scrollview의 Delegate를 통해 스크롤 위치를 파악하고, isHidden 속성 변경하기


스크롤 위치에 따라 스크롤 밖에 구현한 stickyHeaderView의 hidden 속성을 켜주는 식으로 구현할 것이라 했다.
그래서, 스크롤 위치를 파악하기 위해 ScrollView의 delegate를 채택해 줄 것이다.

scrollView.delegate = self

 

사용자가 스크롤할 때 scrollViewDidScroll라는 메서드에서 호출이 되기 때문에,
나는 이 메서드 내에서 현재 스크롤 뷰의 offset y값과 내가 고정시켜 놓은 stickyHeaderView의 y값 + 내비게이션바로 인해 가려지는 높이를 고려해서 isHidden 속성이 false가 되도록 만들어주는 방법을 생각했다.

여기까지 작성하면 스크롤에 따른 StickyHeader가 성공적으로 적용되는 것을 확인할 수 있겠다.
위 내용을 구현한 아래 코드로 다시 한번 프로세스를 확인해 보자.

extension StoreDetailViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let yOffset = scrollView.contentOffset.y

        /// Sticky headerView 높이 고정
        let shouldShowSticky = yOffset >= storeDetailView.customTabBarHeaderView.frame.origin.y + 55
        stickyCustomTabBarHeaderView.isHidden = !shouldShowSticky
    }
}
728x90