본문 바로가기

SwiftUI로 액션시트 띄우기 (iOS 15, macOS Monterey)

기술적인 이야기/애플 플랫폼 개발 2021. 10. 12.
반응형

앞서 작성한 경고창을 띄우는 방법이 최신 SDK에서 변경된 점이 있었던 것과 비슷하게 액션시트(ActionSheet)도 최신 SDK에서 조금 바뀌었다. 그래서 바뀐 내용으로 사용법을 간략히 작성해본다. 당연하게도 Xcode 13 이상의 버전에서 개발해야 하며 iOS 15 혹은 macOS Monterey 등에서만 동작하는 내용이다.

기본 예제

iOS 14까지만 해도 .actionSheet(...) 식의 코드가 있었다. 그런데 이게 최신 SDK에서는 낡음(deprecated) 처리가 되었고 대신 .confirmationDialog(...)를 사용할 수 있게 된다.

아래는 바뀐 코드 예제다.

struct ContentView: View {
    @State private var showingActionSheet = false

    var body: some View {
        Button("Show Action Sheet") {
            showingActionSheet = true
        }
        .confirmationDialog(
            "Select", 
            isPresented: $showingActionSheet, 
            actions: {
                Button("1") { }
                Button("2") { }
                Button("Dismiss", role: .cancel) { }
            }
        )
    }
}

경고창을 띄우던 것과 비슷하게 역시나 액션시트가 떠있는지 여부를 저장하는 스테이트로 showingActionSheet가 있고 이 프로퍼티를 바인딩으로 넘겨주는 식으로 코딩한다. 그리고 버튼이 눌리면 이 프로퍼티를 true로 세팅해서 액션시트를 띄운다. 경고창 띄우기처럼 귀찮은 코딩 스타일이다.

위 코드에서 액션시트의 모양을 담당하는 코드는 뽑아보면 아래와 같은 부분이다.

.confirmationDialog(
    "Select", 
    isPresented: $showingActionSheet, 
    actions: {
        Button("1") { }
        Button("2") { }
        Button("Dismiss", role: .cancel) { }
    }
)

이런 코드가 실행되면 아래와 같은 액션시트가 하단에서 나타난다.

버튼이 눌러졌을 때의 동작은 당연히 각 버튼 구현에서 비어있는 액션 핸들러를 구현하면 된다. 예제에서는 비어있다는 점에 유의하자.

취소(cancel) 역할의 버튼을 별도로 추가하면 제일 하단에 별도로 나타나는 것이 마음에 든다. 하여간 이 자체로는 경고창 띄우는 것과 비교해서 여전히 귀찮기만 하지 어려울 것은 없는 것 같다.

무서운 버튼?!

경고창 버튼 중 파괴적인(destructive) 역할의 버튼을 만들 수 있었다. 자동으로 취소(cancel) 버튼도 생성되기도 하는 그 버튼 말이다. 그게 액션시트에서도 동일하게 동작한다.

아래와 같이 취소 버튼 대신 destructive role의 버튼을 추가해보자.

.confirmationDialog(
    "Select", 
    isPresented: $showingActionSheet, 
    actions: {
        Button("1") { }
        Button("2") { }
        Button("Destruct", role: .destructive) { }
    }
)

그러면 아래와 무서운(?) 일을 하는 destructive 버튼은 빨간색으로 강조가 되어서 표시되고 이와 함께 취소(cancel) 버튼도 함께 나타난다.

destructive 버튼의 역할은 삭제 등의 작업으로 되돌리기가 힘든 작업을 하는 버튼이라는 것을 사용자에게 알려주는 역할이다. 그래서 취소 버튼도 함께 제공해야 한다는 애플의 철학과도 같은 설계로 볼 수 있다.

반응형

타이틀은 어디에?

.confirmationDialog()의 가장 첫 파라미터가 아무런 의미가 없는 것처럼 보인다. 화면 그 어디에도 표시되지 않으니 말이다. 사실 표시가 아예 안 되는 것은 아니고 기본값이 자동(automatic)으로 자동으로 세팅되어 있다. 이 특정 조건에 따라 표시 여부가 결정되는 것 같은데 명확하지는 않다.

이 타이틀을 항상 표시하기 위해선 actions 필드 앞쪽에 위치하는 titleVisibility 필드 파라미터의 값을 .visible로 설정해 주면 된다.

.confirmationDialog(
    "Select", 
    isPresented: $showingActionSheet, 
    titleVisibility: .visible, 
    actions: {
        Button("1") { }
        Button("2") { }
        Button("Destruct", role: .destructive) { }
    }
)

titleVisibility의 값을 .visible로 하면 아래와 같이 타이틀이 항상 표시된다.

타이틀이 얼마나 필수적으로 표시되어야 할지는 잘 모르겠다. 아마도 이것도 가이드라인이 있을 것 같지만 필수적인 요건은 아니니 기본값이 자동으로 세팅되어 있는 것 같다.

관련된 글들

 

SwiftUI에서 경고창(Alert Dialog) 띄우기(iOS 15, macOS Monterey)

iOS 15와 macOS Monterey에서 구현할 수 있는 SwiftUI용 경고창(Alert Dialog)을 띄우는 방법이 새로 추가되었다. 새 방법이 아무래도 코드가 더 간결한 것 같아서 정리해본다. 가장 기본적인 경고창 예제 가

seorenn.tistory.com

728x90
반응형

댓글