iyOmSd/Title: SwiftUI

[SwiftUI] onScrollVisibilityChange 뷰 노출 이벤트

냄수 2024. 11. 27. 18:28
반응형

 

iOS18+에서부터 사용가능한 API를 간단하게

알아보려합니다.

 

지금까지 스크롤뷰에서 특정 뷰가 노출됬다를 표시할땐

onAppear으로만 체크가능했고 혹은 특정지점에 뷰를 하나 숨겨서 체크해왔엇죠!

LazyStack을 쓰지않으면 로드시 모두 onAppear가 실행되서

신경써야했구요!

 

하지만 이번에 알아볼 onScrollVisibilityChange

뷰가 최소 몇% 노출되면 액션을 처리 할 수 있는 함수에요

 

threshold

뷰의 몇%가 보이면 정의된 action이 실행될 것인지를 정합니다.

기본값은 0.5로 뷰의 반이 보이면 action이 실행되요

 

action

threshold만큼 뷰가 보이거나

반대로 스크롤해서 threshold만큼 뷰가 안보여졌을때

실행될 작업을 정의합니다.

 

action에 Bool값으로

해당 %만큼 뷰가 보여지면 true

%만큼 뷰가 가려지면 false값이 반환됩니다.

 

 

간단하게 구현해봅시다

struct ContentView: View {
    
    var body: some View {
        ScrollView {
            LazyVStack {
                colorView(color: .green, height: 400, threshold: 0.5)
                    .onScrollVisibilityChange(threshold: 0.5) { isVisible in
                        print("green: \(isVisible)")
                    }
                colorView(color: .orange, height: 500, threshold: 0.8)
                    .onScrollVisibilityChange(threshold: 0.8) { isVisible in
                        print("orange: \(isVisible)")
                    }
                colorView(color: .gray, height: 600, threshold: 0.2)
                    .onScrollVisibilityChange(threshold: 0.2) { isVisible in
                        print("gray: \(isVisible)")
                    }
            }
        }
        .clipped()
    }
 
    private func colorView(
        color: Color,
        height: CGFloat,
        threshold: CGFloat
    ) -> some View {
        ZStack(alignment: .top) {
            color.frame(height: height)
            Color.black.opacity(0.6)
                .frame(height: height * threshold)
        }
    }
}

 

저희가 집중해야할 부분은 

이부분 입니다.

원하는 색으로 원하는 크기만큼 뷰를그리고

이해하기 쉽도록

threshold에 해당하는 아래부분만 밝게 처리되도록 구현했어요

 

초록색 뷰는 height이 400이고

threshold 0.5라서

뷰의 윗부분은 어둡고 

밑에는 밝죠

 

밝은부분이 보여질때 

onScrollVisibilityChange의 action이 실행됩니다.

 

마찬가지로 주황색 뷰도

threshold가 0.8로 지정되있고

뷰의 0.8지점부터, 즉 뷰의 80%지점(밝은주황색)이 보이면

action이 실행됩니다.

 

반대방향으로 스크롤을 한다면 어떻게 될까요?

뷰의 80%가 보이지않게 되는 시점에 다시 action이 실행됩니다.

 

 

 

반응형