Swift
어서와(SwiftUi) bottomSheet는 처음이지?
Thor_yeom
2022. 11. 7. 23:30
- bottom Sheet에 대해 알아 봅시다.
만들고자 하는것
영상에서 보셨듯이 바텀에서 뷰가 올라고오 '누르시오'버튼을 누르면 애니메이션으로 내려가는 화면을 구현하려고한다. ( 2초뒤에 다시 뷰가 보이는 것은 영상미를 위해 적용하였다)
step 1. 배경색상을 설정한다.
왜 배경 색상을 설정해야 하나요??
처음 제공되는 contentView에 바로 .sheet(ispresented ~ )를 적용하면 오류가 나기에 배경색상의 컬러를 적용해준다.
BgView를 만들어준다.
import SwiftUI
struct BgView: View {
var body: some View {
Color.gray
.edgesIgnoringSafeArea(.all)
}
}
struct BgView_Previews: PreviewProvider {
static var previews: some View {
BgView()
}
}
step2. BgView를 ContentView에 적용한다.
import SwiftUI
struct ContentView: View {
var body: some View {
BgView()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
step3. 팝업 창을 만든다. PopUpView1에서 Rectangle()과 버튼을 만들고 Rectangle() 위에 버튼을 올릴수 있도록 ZStack을 적용한다. 만들어진 PopUpView1을 ContentView에 보여주면 완료
step4. ContentView에 bottomsheet를 만들고 만들어진 PopUpView1을 넣는다.
버튼을 눌렀을 때 상태가 변해야 하기 때문에 @State를 사용해서 상태 변화값을 설정 해준다.( ex) true였을때 버튼을 누르면 false로 바뀜 ) 변하는 값을 PopUpView1에서 입력받아 ContentView로 넘겨야 되기에 PopUpView1에서 @Binding 해준다. 또한 버튼이 눌렸을 때 isShowing이 false로 바꾸어 없어지는 모션을 준다.
import SwiftUI
struct PopUpView1: View {
@Binding var isShowing: Bool
var body: some View {
ZStack {
Rectangle()
.fill(.yellow)
// 하단에만 safeArea를 무시한다.
.edgesIgnoringSafeArea(.bottom)
Button {
print("버튼이 눌렸다.")
isShowing = false
} label: {
Text("버튼")
.font(.largeTitle)
.fontWeight(.bold)
}
}
}
}
struct PopUpView1_Previews: PreviewProvider {
static var previews: some View {
PopUpView1(isShowing: .constant(true))
}
}
여기까지 했으면 bottomsheet에 대해 70%는 적용한것이다.
step5. ContentView에 바텀시트를 적용한다.
struct ContentView: View {
@State private var isShowing: Bool = true
var body: some View {
BgView()
.sheet(isPresented: $isShowing) {
PopUpView(isShowing: $isShowing)
}
}
}
step6. PopUpView1의 사이즈를 조정하는 것은 .sheet의 속성중에 .presentationDetents([])를 사용하여 조절 할 수 있다.
마지막으로 '누르시오' 버튼을 눌렀을 때 2초 뒤 다시 올라오는 모션을 취하려면 비동기 처리(DispatchQueue)를 이용하면 된다.
import SwiftUI
struct PopUpView1: View {
@Binding var isShowing: Bool
var body: some View {
ZStack {
Rectangle()
.fill(.yellow)
// 하단에만 safeArea를 무시한다.
.edgesIgnoringSafeArea(.bottom)
Button {
print("버튼이 눌렸다.")
isShowing = false
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
// 팝업창을 true로 설정하면 .now() + 시간에 따라 다시 나타낼 수 있다.
isShowing = true
}
} label: {
Text("버튼")
.font(.largeTitle)
.fontWeight(.bold)
}
}
}
}
struct PopUpView1_Previews: PreviewProvider {
static var previews: some View {
PopUpView1(isShowing: .constant(true))
}
}