[SwiftUI] Alert와 팝업

Page·2022년 5월 1일
1

SwiftUI

목록 보기
2/18
post-thumbnail

Alert란?

일반적으로 경고 메세지를 보내는 팝업창 용도로 많이 이용한다. 사전 의미도 경보고, 무언가 알리고 싶을 때 SwiftUI에서 이용할 수 있는 뷰다.

상단의 이미지를 표현하기 위해 사용할 수 있다.

SwiftUI 제공 기능

기본적인 사용 방법을 위한 코드를 살펴보자.

import SwiftUI

struct MyAlertView: View {
    
    @State var isShowAlert: Bool = false 
    
    var body: some View {
        Button("show alert") {
            isShowAlert.toggle()
        }
        .alert(isPresented: $isShowAlert) {
            //Alert()
        }
    }
}

기본적으로 Toggling을 통해 값을 변경하며 해당 값이 True일 때 alert 창을 표시한다. 버튼의 마지막에 alert 옵션을 붙여서 사용할 수 있다.

alert를 이용할 수 있는 방법은 많은데 코드를 몇개 찾아보니 가장 위의 방법으로 많이 쓴다. isPresented만 바인딩으로 넘겨주고 action은 클로저 형식으로 작성한다.

클로저에서 반환해야하는 alert는 아래 4가지 형식이 있다.
크게 사용하는데 어려움은 없으니 3번과 1번만 살펴보겠다.

Title, message, dismissButton

struct ContentView: View {
    //showAlert의 bool 타입을 false로 설정
    @State private var showingAlert = false
    
    var body: some View {
        
        Button("Alert 메세지") {
            self.showingAlert.toggle()
        }
        .alert(isPresented: $showingAlert) {
            Alert(title: Text("Title"), message: Text("Message"),
                  dismissButton: .default(Text("Default")))
        }
    }
}

실행 후에 버튼을 누르면 이런 팝업창을 볼 수 있다. 버튼에 대한 옵션을 Default와 Cancel 두가지가 있는데 밑에서 살펴보자.

Title, Message, Primary Button, Secondary Button

위에서 사용한 코드랑 다른 스타일로 작성하겠다.

 var body: some View {
        Button("show alert") {
            isShowAlert.toggle()
        }
        .alert(isPresented: $isShowAlert) {
            let defaultButton = Alert.Button.default(Text("저장"))
            let cancelButton = Alert.Button.cancel(Text("취소"))

            return Alert(title: Text("Alert Title"), message: Text("Alert message"), primaryButton: defaultButton, secondaryButton: cancelButton)
        }
    }

여기서는 두 버튼을 따로 만들어주고 넘겨주는 것외에는 크게 다른 점은 없다.

TextField

팝업창을 띄워고 그곳에서 정보를 입력받고 싶다. 그러면 팝업창에 텍스트필드가 필요한데 기본적으로 제공하는 Alert에서는 텍스트만 작성할 수 있다. 애초에 목적이 알림용도였으니 TextField를 제공할 이유가 없었다.

그래서 팝업으로 텍스트 필드를 이용하고 싶다면 직접 팝업창을 만들어야 하는데 아래 세가지를 이용해서 만들 수 있다.

  1. ZStack
  2. Bool 값 바인딩
  3. Offset

자세히 알아보고 싶다면 아래 Ref2번을 확인해보면 좋다.

ZStack

struct MyTextFieldTester: View {
    
    @State var isShown = false
    var body: some View {
        
        ZStack {
            Button("Show Alert") {
                isShown.toggle()
            }
            MyTextFieldAlert(isShown: $isShown)
        }
      
    }
}

버튼을 통해 토클링을 하자. isShown이 false라면 MyTextFieldAlert가 표시될 것이다. 그 설정은 이곳에서 설정하지 않고 MyTextFieldAlert에서 한다.

Bool 값 바인딩과 offset

struct MyTextFieldAlert: View {
    
    @Binding var isShown: Bool
    @State var text = "Initial Text"
    let screenSize = UIScreen.main.bounds
    let title = "타이틀"
    
    var body: some View {
        
        VStack {
            Text(title)
            TextField("텍스트 필드", text: $text)
            HStack {
                Button("추가") {
                    isShown.toggle()
                }
                Button("취소") {
                    isShown.toggle()
                }
            }
        }.padding()
            .frame(width: screenSize.width * 0.7, height: screenSize.height * 0.3)
            .background(.gray)
            .clipShape(RoundedRectangle(cornerRadius: 20.0, style: .continuous))
            .offset(y: isShown ? 0 : screenSize.height)
    }
}

다른 건 필요없고 offset만 보자. isShown이 true면 y의 offset 값이 0이고 false면 스크린 사이즈 크기만큼 된다. offset 크기 만큼 view가 이동하는데 스크린 사이즈만큼 이동하니 아예 스크린을 벗어나게 되는 것이다. ZStack과 오프셋은 정말 유용하게 이용할 수 있는데 이건 Ref3번에서 확인하자.

이외에도 어떤 형식이든 팝업을 만들고 싶다면 ZStack, Binding, Offset 설정을 통해 손쉽게 만들 수 있다.

Reference

  1. https://seons-dev.tistory.com/27
  2. https://www.youtube.com/watch?v=sOoFBB0VVKI
  3. https://seons-dev.tistory.com/147

0개의 댓글