ScrollView 꾸미기? Deep Dive

2025. 2. 22. 13:23·SWIFT개발

https://www.youtube.com/watch?v=alhFwkbsxrs

역시나 모든 영상의 출처는 WWDC영상 찾아보다가 와 이쁘다 하면서 들어가게 되었다. 

먼저 scrollTargetBehavior은 iOS17이상부터 가능하다.!!! 주의해야할듯. 사용하고 싶어도 못쓸수가 있어요~

    @available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
    nonisolated public func scrollTargetBehavior(_ behavior: some ScrollTargetBehavior) -> some View

흠 까보니까 안에 ScrollTargetBehavior라는 놈을 받네. 그런데 요놈은 프로토콜이다. 

public protocol ScrollTargetBehavior {
    func updateTarget(_ target: inout ScrollTarget, context: Self.TargetContext)

    /// The context in which a scroll behavior updates the scroll target.
    typealias TargetContext = ScrollTargetBehaviorContext
}

ScrollTargetBehavior는 스크롤 가능한 뷰의 스크롤 동작을 정의하는 프로토콜. 즉, SwiftUI의 ScrollView가 스크롤할 때 어떤 방식으로 동작할지를 결정할 수 있도록 해줍니다.(말 그대로)

이 프로토콜을 채택하면 updateTarget(_ target: inout ScrollTarget, context: Self.TargetContext) 메서드를 구현하여 스크롤 타겟을 직접 제어할 수 있어요.

1. 사용자가 스크롤을 멈췄을 때

• 스크롤이 멈출 위치를 자연스럽게 계산한 후, 그 위치를 target 값으로 전달해요.

• 개발자가 이 값을 조정하면 원래 멈출 위치 대신 원하는 위치로 스크롤을 이동할 수 있어요.

2. 스크롤 가능한 뷰의 크기가 변경될 때

• 화면 회전이나 레이아웃 변화로 인해 스크롤 뷰 크기가 바뀌면, 시스템이 적절한 스크롤 위치를 계산해요.

• 이때도 개발자가 원하는 위치로 수정할 수 있어요.

 

기본 제공 ScrollTargetBehavoir 유형

1. .paging

이제 다시 맨위의 코드를 보면 .paging속성을 보자. 스크롤이 컨테이너 크기에 맞춰 한번에 한페이지씩 이동하게된다. 사실 이 기능을 재작년에 내가 개발했던 앱에서 정말 필요했던 기능이다. 하지만 그때는 이걸 몰랐기에 ScrollViewReader와 GeometryReader로 위치를 파악하여 하려했지만 잘안되어서 탭뷰로 했던 경험이 있다. 

2. .viewAligned

위에께 컨테이너 기반의 도형이였다면 이놈은 뷰 기반 형상에 정렬하는 동작이다. 개별요소가 스크롤 뷰 내에서 중앙에 유지되고 싶을때 사용. 

그런데 viewAligned 에는 limitBehavoir라는것을 설정할 수 있다. 여기에는 총 3가지 케이스가 있다. 

1. automatic : SwiftUI가 최적의 제한을 자동으로 결정합니다.

2. always: 스크롤할 수 있는 아이템 수를 제한하여 한 번에 정해진 개수만 이동할 수 있도록 합니다. 

3.  never: 스크롤에 대한 제한 없이 자유롭게 이동할 수 있습니다.

never로 하면 한페이지만 넘어가는게 아니라 힘에따라 여러개가 넘어갈 수도 있는 차이인듯하다. 

사용자 정의 ScrollTargetBehavior 생성하기

 

SwiftUI의 기본 동작 외에도, ScrollTargetBehavior 프로토콜을 준수하여 직접 커스텀 스크롤 동작을 정의할 수 있습니다.

 

예를 들어, 스크롤이 항상 150포인트 단위로 정렬되도록 하는 커스텀 동작을 만들 수 있습니다.

struct CustomScrollTargetBehavior: ScrollTargetBehavior {
    func updateTarget(_ target: inout ScrollTarget, context: TargetContext) {
        target.rect.origin.x = round(target.rect.origin.x / 150) * 150
    }
}
ScrollView(.horizontal) {
    LazyHStack {
        ForEach(0..<10, id: \.self) { index in
            Text("커스텀 \(index)")
                .frame(width: 150, height: 100)
                .background(Color.red.opacity(0.3))
                .cornerRadius(10)
        }
    }
    .scrollTargetLayout()
}
.scrollTargetBehavior(CustomScrollTargetBehavior())

 

ScrollTransition

스크롤 뷰에서 특정요소가 스크롤될때 애니메이션효과 적용할수 있도록 한다. 이 기능을 통해 스크롤에 따라 뷰의 크기, 위치 ,투명도 등을 동적으로 변화 ㄱㄴ.

@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
extension View {
    nonisolated public func scrollTransition(
        _ configuration: ScrollTransitionConfiguration = .interactive,
        axis: Axis? = nil,
        transition: @escaping @Sendable (EmptyVisualEffect, ScrollTransitionPhase) -> some VisualEffect
    ) -> some View
}

configuration:

• ScrollTransitionConfiguration 타입으로, 스크롤 애니메이션의 설정을 정의합니다.

• 기본값은 .interactive이며, 스크롤과 함께 동적으로 변화하는 방식입니다.

axis:

• 스크롤이 적용될 축을 지정합니다.

• nil을 설정하면 내부에서 가장 가까운 ScrollView의 방향을 자동 감지합니다.

transition:

• ScrollTransitionPhase를 받아서 특정 VisualEffect를 적용하는 클로저입니다.

• EmptyVisualEffect를 기반으로, 투명도, 블러, 크기 변경 등의 효과를 조합할 수 있습니다.

자 그림을 보면서 더해 보자. phase에서 value로 떨어진 거리를 결정하고 회전효과에 적용하였다.  isIdentity는 화면에 완전히 표시되면 true고 아니면 false

이건 영상을 보면서 따라오면 더 이해가 잘될수있다. 창문형식으로 저 content와 offset을 잘이용하여 시차로 밀리는 뷰도 그릴수 있다. 나중에 꼭써봐야할 기능같다. 

 

 

'SWIFT개발' 카테고리의 다른 글

이미지 최적화 적용하기  (1) 2025.03.06
Preview는 어떻게 그림을 그리는 걸까? is that hotreload?  (0) 2025.03.01
MemoryLeak을 찾아보자(강한참조순환인가?) - 실전편2  (0) 2025.01.16
Memory Leak을 찾아보자 실전편(1)  (0) 2025.01.14
Alamofire error code handling  (4) 2024.12.17
'SWIFT개발' 카테고리의 다른 글
  • 이미지 최적화 적용하기
  • Preview는 어떻게 그림을 그리는 걸까? is that hotreload?
  • MemoryLeak을 찾아보자(강한참조순환인가?) - 실전편2
  • Memory Leak을 찾아보자 실전편(1)
2료일
2료일
좌충우돌 모든것을 다 정리하려고 노력하는 J가 되려고 하는 세미개발자의 블로그입니다. 편하게 보고 가세요
  • 2료일
    GPT에게서 살아남기
    2료일
  • 전체
    오늘
    어제
    • 분류 전체보기 (121)
      • SWIFT개발 (30)
      • 알고리즘 (25)
      • Design (6)
      • ARkit (1)
      • 면접준비 (31)
      • UIkit (2)
      • Vapor-Server with swift (3)
      • 디자인패턴 (5)
      • 반응형프로그래밍 (12)
      • CS (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    ios
    Swift
    UDP
    오블완
    filter
    RxSwift
    티스토리챌린지
    Protocol
    알고리즘
    kingfisher
    cs
    uikit
    프로그래머스
    socket
    Coremotion
    비동기
    METAL
    actor
    SwiftUI
    image
    combine
    Vapor
    CoreLocation
    TCA
    Dependency
    shader
    TCP
    HIG
    Python
    operators
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
2료일
ScrollView 꾸미기? Deep Dive
상단으로

티스토리툴바