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))
    }
}