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 |