SwiftUI - PinnedScrollableViews (a.k.a Sticky View)
안녕하세요. 그린입니다🍏
이번 포스팅에서는 SwiftUI에서 PinnedScrollableViews라는것에 대해 알아보겠습니다🙌
이걸 알아보게 된 배경은 프로덕트의 기능을 구현하다 스크롤뷰로 감싸진 VStack에서 헤더 뷰를 구성하고 이 헤더 뷰는 스크롤을 아무리 내려도 상단에 고정시켜야 했습니다.
이에 LazyVStack 구현 시 파라미터에 pinnedViews라는 옵션이 있었어요.
pin하니까 역시 무언가 고정해준다는 느낌을 확 받았고, 이 타입은 PinnedScrollableViews라는것을 알게되었습니다.
참고로 이러한 뷰를 Sticky View라고 부릅니다😊
그럼 우선 PinnedScrollableViews가 무엇인지 알아보고 적용해보시죠!
PinnedScrollableViews?
iOS 14에서부터 사용가능하며 스크롤 뷰의 경계에 고정을 시켜줄 수 있는 뷰 타입 집합입니다.
선언은 아래와 같습니다.
struct PinnedScrollableViews
해당 타입은 staic 변수로 기본적으로 두개의 고정 위치 선택을 위한 값을 제공해줍니다.
sectionHeaders와 sectionFooters를 통해 상 / 하단 원하는 위치에 고정이 가능하죠.
또한 조금 더 커스텀하게 UInt32의 원시값을 이용해 PinnedScrollableViews를 직접 만들 수 있습니다.
요정도면 알면 충분합니다!
그럼 바로 사용해보도록 하죠🕺🏻
LazyVStack에서 PinnedScrollableViews 사용해 상단 고정 스크롤 뷰 만들기
말보다 코드부터😀
import SwiftUI
// StickyView
struct ContentView: View {
let colors: [Color] = [.red, .green, .yellow, .black, .gray, .blue, .brown, .purple, .orange]
var body: some View {
VStack {
TitleView()
ScrollView(showsIndicators: false) {
ScrollTitleView()
LazyVStack(pinnedViews: .sectionHeaders) {
Section(header: HeaderView()) {
VStack {
ForEach(colors, id: \.self) { color in
CellItemView(color: color)
.padding(.horizontal, 10)
}
}
}
}
}
}
}
}
private struct TitleView: View {
fileprivate var body: some View {
Text("Variant Colors")
.font(.largeTitle)
.bold()
}
}
private struct ScrollTitleView: View {
fileprivate var body: some View {
Text("ScrollView Start Point")
.font(.largeTitle)
.bold()
}
}
// Sticky Header
private struct HeaderView: View {
fileprivate var body: some View {
HStack {
Spacer()
Text("This is Header")
.font(.title)
.bold()
.foregroundColor(.blue)
Spacer()
}
.background(.white)
}
}
private struct CellItemView: View {
private var color: Color
fileprivate init(color: Color) {
self.color = color
}
fileprivate var body: some View {
RoundedRectangle(cornerRadius: 20)
.foregroundColor(color)
.frame(height: 100)
}
}
우선 코드가 간단해서 다른 부분은 생략하고 중요한 부분만 설명하겠습니다.
LazyVStack 생성 시 pinnedViews 조건을 sectionHeaders로 줍니다.
그럼 스티키하게 헤더는 상단에 고정되죠!
그 다음 Section header에 만든 HeaderView를 담아줍니다.
그러면 이제 정말 고정된 스크롤 헤더 뷰 완성🚀
그 밑으로는 자유롭게 구성해주면 됩니다🙌
여기서 중요한점은 Sticky Header를 만들때 background를 주지 않으면 오버레이처럼 중첩되어 나타나보입니다.
아래와 같이 말이죠😭
이런 불상사를 막기 위해 Sticky Header를 만들때 background의 색상을 white로 주면 충분해집니다.
아마도 PinnedScrollableViews를 위해 만들어지는 Header의 백그라운드는 clear해서 그런것 같아요.
그럼 이제 돌려보죠!
챠란~~ 원하는 결과를 얻었습니다. (+1)
마무리
Sticky 구현을 처음 해봤는데 아주 유용하고 요긴하게 두루두루 휘뚜루마뚜루 잘 쓸것 같습니다👍
위 예시 코드는 제 깃헙 레포에 있으니 필요하다면 참고해주세요😀
https://github.com/GREENOVER/playground/tree/main/PinnedScrollableViews
GitHub - GREENOVER/playground: 학습을 하며 간단한 예제들을 만들어 보는 작고 소중한 놀이터
학습을 하며 간단한 예제들을 만들어 보는 작고 소중한 놀이터. Contribute to GREENOVER/playground development by creating an account on GitHub.
github.com
[참고 자료]
https://developer.apple.com/documentation/swiftui/pinnedscrollableviews
Apple Developer Documentation
developer.apple.com