[iOS] Dimming View

RudinP·2024년 6월 25일
0

Study

목록 보기
236/258
post-thumbnail

Dimming

  • 조명이나 화면 밝기를 조정하는 것

Dim View

  • 스크롤에 따라 뷰의 가시성을 조절하는 뷰를 만드는 방법을 설명한다.

1. 뷰로부터 첫번째 셀까지의 Inset 구하기(위쪽 여백 구하기)

  • collection 뷰의 높이에서 첫번째 셀의 높이, safeAreaInset의 top, safeAreaInset의 bottom, 그리고 section inset을 빼주어야 한다.

2. 해당하는 뷰에 구한 Inset 설정하기

3. selectItem으로 해당 셀로 이동

  • Inset을 바꾼다고 자동으로 셀이 이동하지 않는다.
func adjustContentInset(){
        let indexPath = IndexPath(item: 0, section: 0)
        if let first = detailCollectionView.cellForItem(at: indexPath){
            let topInset = detailCollectionView.frame.height - first.frame.height - view.safeAreaInsets.top - view.safeAreaInsets.bottom - 20//section inset
            detailCollectionView.contentInset = UIEdgeInsets(top: topInset, left: 0, bottom: 0, right: 0)
            //contentInset을 바꾼다고 자동으로 셀이 이동하지 않으므로 셀을 원하는 위치로 이동시켜야 한다.
            detailCollectionView.selectItem(at: indexPath, animated: false, scrollPosition: .bottom)//scrollPosition: 최종 위치
        }
    }

주의할 점: viewDidLoad()는 컬렉션뷰에 셀이 표시되기 전에 호출된다.

  • 따라서 해당 부분에서 adjustContentInset()을 호출하면 실패한다.
  • viewDidAppear()에서 호출하면 작동하기는 하나, 어색하게 된다.(이미 컬렉션뷰가 출력된 뒤에 inset이 적용됨)
  • viewDidLayoutSubviews()에서 호출하면 된다.
    • collectionView가 subview로 배치되고 나서 셀에 접근 가능하기 때문이다.

4. viewDidLayoutSubviews에서 호출

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        adjustContentInset()
    }

5. UIScrollViewDelegate로 스크롤에 따른 가시성 변경 구현

  • 스크롤 할 때마다 스크롤 위치를 파악할 필요가 있다.
  • 여기에 맞게 알파 값을 변경한다.

  • 스크롤이 되는 뷰들은 모두 UIScrollView 프로토콜을 채택하므로 해당 델리게이트를 구현할 수 있다.
  • 파라미터의 UIScrollView를 그대로 사용하거나 다운캐스팅하면 된다.

  • 스크롤 위치는 contentOffset으로 확인 가능하다.
  • 애니메이션 효과가 필요하면 setContentOffset을 사용하면 된다.

#function, contentOffset.y 출력 결과

  • offset 의 0의 위치는 화면의 가장 위쪽이다.
  • 초기에 네비게이션바가 있다면 이를 조정하기 위해 scrollViewDidScroll이 호출된다. (-149)
  • 위에서 collectionView의 inset을 이동하였으므로 -605로 또 한번 델리게이트가 실행된다.
  • 음수인 이유는 원래 collectionView의 위치보다 아래로 이동했기 때문이다.
  • 윗방향으로 스크롤하면 양수가 된다.

스크롤 비율에 따라 dimView 알파값 변경

  • initialOffsetY는 아까 collectionView 이동 시 최종 위치 y값 저장
extension PlanetDetailViewController: UIScrollViewDelegate{
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print(#function, scrollView.contentOffset.y)
        
        let y = scrollView.contentOffset.y
        let half = scrollView.bounds.size.height / 2
        
        //스크롤 절반까지 서서히 dimView의 알파가 0.4가 되도록 하고 그 이상은 0.4 유지.
        if y <= initialOffsetY{
            dimView.alpha = 0.0
        } else if y <= -half{ //음수값이라 - 붙여서 계산해야 함.
            let progress = (initialOffsetY - y) / (initialOffsetY + half)
            dimView.alpha = progress * 0.4
        } else {
            dimView.alpha = 0.4
        }
    }
}
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글