
Bottom Drag Sheet를 커스텀으로 만들게 된 이유
![]()
1. .sheet() 모디파이어를 이용
-> 탭뷰 뒤에 바텀시트를 두고 싶었지만 아무리 해도 바텀시트가 탭뷰 앞으로 와서 탭뷰를 계속 가리게 되는 이슈가 있었다.
2. UIKit를 활용해 커스텀 뷰 생성
-> 이 방법은 정상적으로 작동했지만 나는 UIKit가 아니라 SwiftUI를 선호하기 때문에 기각했다.
3. BottomSheet 패키지 이용
-> 나와 같은 문제를 겪는 사람이 많았는지 패키지로 만들어 놓은 사람이 있었고 이걸 활용하여 만들었으나 뭔가 이끌림이 없어서 기각했다.
스택오버 플로우, 블로그 등을 잔뜩 찾아 봤지만 어떤 글에서도 해결할 수가 없어서 결국 SwiftUI에서 커스텀 뷰를 만들어보기로 했다.
Custom Bottom Drag Sheet 코드
import SwiftUI
struct BottomDragSheet: View {
@State private var currentOffset: CGFloat = 0
@State private var endOffset: CGFloat = 0
let sheetHeight: CGFloat = 120 //바텀 시트 높이 설정
let sensitivity: CGFloat = 2 //드래그 민감도 (1이 기본, 0.5는 덜 민감, 2는 더 민감)
var body: some View {
ZStack {
GeometryReader { geometry in
let sheetPosition = geometry.size.height - sheetHeight
VStack {
Capsule()
.fill(Color.gray)
.frame(width: 80, height: 4)
.padding(.top)
ScrollView{} //여기 바텀시트안에 넣고 싶은 뷰 넣기
}
.frame(maxWidth: .infinity)
.background(Color.white.cornerRadius(30))
.offset(y: sheetPosition + currentOffset)
.gesture(
DragGesture()
.onChanged { value in
withAnimation(.spring()) {
currentOffset = value.translation.height * sensitivity + endOffset
}
}
.onEnded { value in
withAnimation(.spring()) {
// 큰창
if currentOffset < -sheetPosition / 2 {
currentOffset = -sheetPosition
// 중간 창
} else if currentOffset < -100 {
currentOffset = -sheetPosition / 2
// 작은 창
} else {
currentOffset = 0
}
endOffset = currentOffset
}
}
)
}
}.edgesIgnoringSafeArea(.bottom)
}
}
#Preview {
ZStack {
Color.gray.ignoresSafeArea()
BottomDragSheet()
}
}
![]()
import SwiftUI
import MapKit
struct FirstView: View {
var body: some View {
ZStack {
Map()
BottomDragSheet()
}
}
}
import SwiftUI
struct TabViewBottomSheet: View {
@State private var selection = 1
var body: some View {
TabView(selection:$selection) {
FirstView()
.tabItem {
Image(systemName: "house")
}.tag(1)
SecondView()
.tabItem {
Image(systemName: "list.bullet")
}.tag(2)
MyPageView()
.tabItem {
Image(systemName: "person")
}.tag(3)
}
}}
이제 앱을 개발하다가 TabView 뒤에 Bottom Drag Sheet를 넣고 싶을때 이 코드를 활용 해야겠다.