[ActionSheet] title 안나오게 할 수 있을까?

2023. 7. 31. 17:29iOS 개발/SwiftUI

SwiftUI로 카카오톡 채팅을 구현하던중 채팅방을 나갈때 뜨는 sheet가 무엇인지 찾아보았다.

구글링을 해보니 ActionSheet라는 것을 쓴다고 한다.

구현 코드는 이렇다 !

struct ContentView: View {
    
    @State private var kakaoActionSheet = false 
    
    var body: some View {
        VStack {
            Button {
                kakaoActionSheet = true
            } label: {
                Image(systemName: "door.left.hand.open")
            }
            .actionSheet(isPresented: $kakaoActionSheet) {
                ActionSheet(title: Text("채팅방을 나가면 대화내용이 모두 삭제되고\n채팅목록에서도 사라집니다."), 
                			buttons: [.destructive(Text("나가기")),
                            		  .destructive(Text("신고하고 나가기")),
                                      .cancel(Text("취소"))])
            }
        }
       
    }
}

.sheet나 .alert와 같이 @State변수를 만들고 true값으로 바뀔 때 동작하는 것은 같다.

코드는 view의 modifier로 .actionSheet를 달아주고 ,

isPresented에 @State변수 값 ,

그 안에 ActionSheet를 만들어 주면된다. 

 

구현 영상

ActionSheet(title: Text, message: Text?, buttons: [ActionSheet.Button])

ActionSheet의 형태는 이렇다.

먼저 title은 반드시 Text로 써줘야 한다. 안써주면 넣으라고 에러가 뜬다..

 

 

message는 title밑에 나온다. massage는 없어도 빌드가 된다.

그래서 내가 생각하기엔 message가 옵셔널 타입이니까 message는 없어도 되고 title,buttons는 반드시 써줘야 된다고 생각했다.

그래도 혹시 몰라서 buttons도 지워봤다.

근데 이게 왠일..! buttons는 안써도 title처럼 넣어주라는 에러가 안뜬다 ! 

 

 

그럼 어떻게 나오는거지..?

 

 

버튼은 안써줘도 .cancel 버튼이 하나가 나온다. 음 그렇다면..

 

 

역시 공식문서를 찾아보니 .cancel 버튼 하나가 초기화가 돼 있다 !!

이렇게 채팅방 나가기를 구현해서 ActionSheet를 알게 되었다~~

 

 

잠시 후..

ActionSheet는 채팅방 나가기 뿐 아니라 전화링크로 올라올때도 쓰인다. 이런식으로..!

 

 

근데 이 ActionSheet는 위에 title이 없다.

하지만 title은 반드시 써줘야 되기 때문에 title에 값을 ""로 주면 저렇게 뜨겠지 하고 

코드를 구현해보았다.

struct ContentView: View {
    
    @State private var callActionSheet = false
    
    var body: some View {
        VStack {
            Button {
                callActionSheet = true
            } label: {
                Image(systemName: "phone")
            }
            .actionSheet(isPresented: $callActionSheet) {
                ActionSheet(title: Text("") , buttons: [.default(Text("통화  1899-9900")),
                    .cancel(Text("취소"))])
            }
        }
       
    }
}

결과는 .. !! 

 

 

어라.. title에 빈값을 줘도 자리는 그래도 차지하고 있다..

하지만 title에는 Text를 반드시 넣어줘야 한다

구글링을 해봤더니 방법을 찾았다~~~~~!!

 

우선 위에서 공부했던 ActionSheet는 deprecated 되었다고 한다!

 

 

deprecated는 애플에서 더 이상 지원하지 않는다는 것이다.

하지만 애플은 무조건 deprecated를 시키는게 아니라 대체할 것을 만들고 시키니까 걱정안해도 된다.

 

 

위 처럼 ActionSheet 대신에 confirmationDialog를 사용하라고 친절하게 말해준다.

ActionSheet를 지우고 confirmationDialog로 코드를 바꿨다.

struct ContentView: View {
    
    @State private var callActionSheet = false
    
    var body: some View {
        VStack {
            Button {
                callActionSheet = true
            } label: {
                Image(systemName: "phone")
            }
            .confirmationDialog("",  isPresented: $callActionSheet) {
                Button("통화 1899-9900", role: .none) {}
                Button("취소", role: .cancel) {}
                
            }
        }
    }
}

구현방식도 ActionSheet와 비슷하다.

modifier로 .actionSheet -> .confirmationDialog 바꿔주고

titlekey에 String 값,

isPresented에 @State변수 값 , 

그 안에 Button들을 넣어주면 된다.

 

ActionSheet에서 title에 반드시 Text를 써줘야 했던것과 다르게 title 영역이 사라졌다.

그럼 titlekey에 ""를 안주고 값을 넣어주면 title이 생기겠지? "전화걸기" 라는 값을 넣어주자 !

 

 .confirmationDialog("전화걸기",  isPresented: $callActionSheet) {
                Button("통화 1899-9900", role: .none) {}
                Button("취소", role: .cancel) {}
                
}

 

결과는...!

 

 

어라..? 역시 단순하지 않다ㅎㅎㅎㅎ 원인이 뭔지 찾아보자..

func confirmationDialog<A>(
    _ titleKey: LocalizedStringKey,
    isPresented: Binding<Bool>,
    titleVisibility: Visibility = .automatic, @ViewBuilder actions: () -> A
) -> some View where A : View

내가 쓴 confirmationDialog의 형태를 보면 이렇게 돼있다.

딱 봐도 titleVisibility를 써야 될거 같지 않나!

따로 써주지 않으면 기본값으로 .automatic으로 돼있는데 안나오는걸 보니 바꿔 줘야겠다.

.confirmationDialog("전화걸기",  isPresented: $callActionSheet, titleVisibility: .visible) {
                Button("통화 1899-9900", role: .none) {}
                Button("취소", role: .cancel) {}   
}

titleVisibility의 타입은 Visibility로 돼있다.

 

 

Visibility는 애플에서 제공하는 enum이다.

 

 

 

Visibility의 case는 automatic, visible , hidden으로 돼있다. 

automatic이 정확히 뭔지는 잘모르겠지만 visible과 hidden은 그냥 단어만 봐도 보여짐,  숨김이 명확하다.

그래서 나는 visible로 썼다!! 결과는..!!

 

 

역시 내가 생각한대로 title이 나왔다!!

 

당근마켓도 보면 title칸이 없는걸 보니 confirmationDialog를 쓴것같다.

(SwiftUI로 앱제작이 됐다면 UIkit의 ActionSheet는 title을 안보이게 할 수 있는것 같다.)

 

내가 배운점은 

AcitonSheet는 title에 Text가 들어가야 돼서 자리를 반드시 차지한다.

confirmationDialog는 titleVisibility로 title을 숨기고 보이게 할 수 있다.

AcitonSheet는 deprecated 되었으니 이왕이면 confirmationDialog 쓰는게 좋겠다 !

'iOS 개발 > SwiftUI' 카테고리의 다른 글

[TIL] 포도맛(스레드) 에러  (1) 2024.03.16
[Codable] color값 사용하기(연산프로퍼티)  (0) 2023.07.12
[Clone App] Login - SwiftUI (#1)  (0) 2023.07.06
[SwiftUI] VStack  (0) 2023.06.19