-
안녕하세요. 그린입니다🍏
이번 포스팅에서는 PopupView라는 라이브러리에 대해 학습해보겠습니다🙌
SwiftUI에서 플로팅/토스트 메시지 혹은 팝업이나 바텀 시트를 노출해야 될 경우 기본적으로 제공하는 API를 사용하여도 되고 아니면 조금 더 커스텀하게 만들어서 사용해도 되는데 요 것들을 조금 더 편리하게 제공해주는 라이브러리가 있더라구요!
바로 오늘 학습해볼 PopupView입니다🙋🏻
PopupView
단순히 View Modifier로 간단히 사용할 수 있도록 구현되어 있어 우선 사용에 대해 알아보겠습니다.
SPM / cocoapods / carthage 모든 방식으로 가져와서 사용할 수 있습니다.
플로팅부터 한번 바로 사용해볼께요!
import SwiftUI import PopupView struct ContentView: View { @State var isPresentedFloating: Bool = false var body: some View { VStack { Button( action: { isPresentedFloating.toggle() }, label: { Text("Show Floating") } ) } .padding() .popup(isPresented: $isPresentedFloating) { FloatingView() } customize: { $0 .type(.floater()) .position(.top) .animation(.spring()) .closeOnTapOutside(true) .backgroundColor(.black.opacity(0.5)) } } } private struct FloatingView: View { var body: some View { HStack { Spacer() Text("This is Floating") .font(.headline) .padding(.vertical, 10) Spacer() } .background(Color.white) .cornerRadius(20) .padding(.horizontal, 20) } }
요렇게 PopupView 라이브러리를 import 해줍니다.
그 다음 해당 플로팅뷰가 뜰 뷰에 popup view modifier를 붙여주면 됩니다.
여기서 isPresented는 Binding 프로퍼티로 노출 여부의 바인딩 값에 사용될것을 넣어주면 됩니다.
(이 값은 필수 매개변수로 꼭 넣어줘야합니다.)
그 다음 보여줄 컨텐츠를 자유롭게 구성하고 customize 이스케이핑 클로저를 이용해 노출 레이아웃을 자유롭게 구성하면 끝이에요!
그럼 아래와 같이 정상적으로 동작할거에요.
그럼 들어갈 컨텐츠는 각자 커스텀하게 구현한다치고 customize를 통해 어떻게 컨트롤할 수 있는지 뭘 받아올 수 있는지 체크해보겠습니다🕺🏻
PopupView의 Optional Parameters
위에서 간단히 말했듯 customize 클로저에서 선택적으로 기능 및 레이아웃에 사용될 매개변수를 지정해줄 수 있습니다.
type
floater, toast 혹은 default 총 3가지의 PopupType을 열거로 가지고 있습니다.
플로팅은 위와 같이 해당 뷰 자체에서 패딩이 잡히지만 toast 타입은 기기 전체에서 패딩이 잡히드라구요.
요렇게 말이죠.
그래서 별도 패딩을 넣어주거나 하는 작업이 동반되어야 할 것 같습니다.
반면 floater에는 자체적으로 VerticalPadding과 UseSafeAreaInset이라는 매개변수가 있습니다.
토스트와 다른점이 요 UseSafeAreaInset 매개변수의 차이로 위와 같은 현상이 발생하네요😄
해당 플로터 패딩에 SafeArea를 포함할지에 대한 여부입니다.
position
어디를 기준으로 나타날지에 대한 값입니다.
기본적으로 Position 열거 타입으로 top, bottom 두가지로 분류됩니다.
animation
어떻게 노출될지에 대한 애니메이션 동작 구현입니다.
저의 위 예시는 spring 애니메이션으로 구현된것이고 상황에 맞게 easeIn, easeOut, linear 혹은 커스텀하게 애니메이션을 구성해 사용하면 됩니다.
autohideIn
해당 팝업 노출이 사라지는 시간을 지정할 수 있습니다.
Double 타입으로 받습니다.
dragToDismiss
드래그하여 노출 활성/비활성화를 시킬 수 있습니다.
기본적으로 Position과 같이 물리는데 top 포지션일 경우 위쪽 드래깅 bottom일 경우 아래쪽 드래깅을 할 수 있습니다.
디폴트로 true로 되어 있으며 상황에 따라 false로 변경해 사용하면 됩니다.
closeOnTap
해당 팝업을 클릭 해 노출 활성/비활성화를 시킬 수 있습니다.
closeOnTapOutside
해당 팝업의 외부 영역을 클릭 해 노출 활성/비활성화를 시킬 수 있습니다.
backgroundColor
팝업 외부 영역의 배경 색상을 지정할 수 있습니다.
기본적으로는 Clear 색상으로 구성되어 있고 팝업 노출 될 때 팝업에 집중 시키고 외부 영역을 약간 딤드 처리하고 싶다면 제 예시와 같이 색상을 지정해줄 수 있습니다.
isOpaque
기본값으로는 false로 되어 있으며 팝업이 호출된 뷰 위에서 올려지며 나머지 설정들은 그 상단 뷰가 적용되지 않습니다.
즉 true 설정할 경우 전역적으로 처리할 수 있습니다.
다만 closeOnTapOutside 설정이 되어 있을 경우 항상 true로 isOpaque도 설정되어 있습니다.
차이를 한번 보시죠!
주석단 부분의 true/false 설정을 통해 변경할 수 있어요.
import SwiftUI import PopupView struct ContentView: View { @State var isPresentedFloating: Bool = false var body: some View { VStack { Text("Hello PopupView !") Spacer() Button( action: { isPresentedFloating.toggle() }, label: { Text("Show Floating") .popup(isPresented: $isPresentedFloating) { FloatingView() } customize: { $0 .type(.floater()) .animation(.spring()) // 요 부분 T/F 설정 .isOpaque(false) .backgroundColor(.black.opacity(0.5)) } } ) } .padding() } }
우선 false 설정입니다.
보시는것처럼 전체적인 영향이 아닌 해당 Show Floating 버튼 View 영역에서 백그라운드 처리가 되는걸 확인할 수 있죠.
반면 true 설정이라면!?
네비게이션 바 및 타 영역을 포함하여 전체적으로 가져감을 확인할 수 있습니다!
자 그럼 이렇게 floating과 toast를 기본적으로 사용하는 방법과 필요한 매개변수 설정에 대해 알아봤어요🙌
이어서 간단히 바텀 시트를 구현해볼께요!PopupView로 바텀 시트 구현하기
바텀 시트를 구현하려면 toast를 사용하여 쉽게 구현할 수 있습니다.
왜냐면 대부분 bottom Sheet라는것은 뷰가 아닌 기기 즉 safeArea 영역을 넘어 전체적으로 뷰를 그려주며 나타나는게 일반적이니까요.
그럼 코드로 보시죠!
import SwiftUI import PopupView struct ContentView: View { var body: some View { BottomSheetView() } } private struct BottomSheetView: View { @State var isPresentedBottomSheet: Bool = false var body: some View { VStack { Button( action: { isPresentedBottomSheet.toggle() }, label: { Text("Show Bottom Sheet") } ) } .padding() .popup(isPresented: $isPresentedBottomSheet) { VStack { HStack { Spacer() Text("This is Bottom Sheet") .padding(.top, 10) Spacer() } Spacer() } .background(Color.white) .frame(height: 150) .cornerRadius(20) } customize: { $0 .type(.toast) .position(.bottom) .dragToDismiss(true) .closeOnTapOutside(true) .backgroundColor(.black.opacity(0.5)) } } }
요렇게 customize 부분만 보면 toast 타입이고 아래에서 노출되며 drag에 대해 지원하게 구성하면 됩니다.
그럼 동작은 바로 요렇게~~!
자 이렇게 생각한것처럼 나옵니다!
마무리
이렇게 편리한 라이브러리가 있었네요!
사실 저는 커스텀하게 직접 구현하는걸 더 선호하긴 하지만 빠른 구현을 요할때는 사용해봐도 좋을것 같습니다😄
위 해당 코드 예제는 아래 제 깃헙 레포에 올려뒀으니 필요하시면 참고해주세요ㅎㅎ
https://github.com/GREENOVER/playground/tree/main/popupTest
[참고 자료]
'Library' 카테고리의 다른 글
Firebase - Remote Config (67) 2024.03.11 Get 라이브러리로 심플한 웹 API 클라이언트 구현하기 (4) 2023.02.13 SwiftUI-Introspect (2) 2022.09.15 TCACoordinators (6) 2022.08.15 SkeletonUI (0) 2022.07.25