-
SwiftUI + TCA: confirmationDialog를 활용한 액션 시트 구현 (예제 포함)개발/Swift 2025. 2. 7. 09:11반응형
SwiftUI + TCA: 실전 프로젝트로 완성하는 차세대 iOS 아키텍처 강의 | 덤벨로퍼 - 인프런
덤벨로퍼 | 복잡한 SwiftUI 상태 관리, TCA (The Composable Architecture)로 깔끔하고 견고한 앱을 만드세요. 실전 프로젝트 예제로 핵심만 빠르게 배웁니다. , SwiftUI + TCA: 실전 프로젝트로 완성하는 차세대
www.inflearn.com
SwiftUI에서 **TCA(The Composable Architecture)**를 활용하여 사용자에게 액션 선택지를 제공하는 **액션 시트(Action Sheet)**를 효율적으로 구현하는 방법에 대해 알아보겠습니다.특히 confirmationDialog 수식어를 중심으로 상세한 구현 방법을 다룰 예정이니, Swift 및 TCA 기반 iOS 앱 개발자분들께 유용한 정보가 되기를 바랍니다.**confirmationDialog**를 활용한 액션 시트 구현 방법은 다음과 같습니다.우선, .confirmationDialog 수식어의 주요 옵션들을 살펴보겠습니다.•.confirmationDialog(<#T##LocalizedStringKey#>, isPresented: <#T##Binding<Bool>#>, titleVisibility: <#T##Visibility#>, actions: <#T##(T) -> A#>)
이 옵션들을 하나씩 자세히 살펴보며, 어떻게 활용하는지 알아보겠습니다.- 1. 타이틀 영역 (LocalizedStringKey 또는 String): 액션 시트의 제목을 정의하는 부분입니다.
- 2. isPresented (Binding<Bool>): 액션 시트의 표시 여부를 결정하는 Bool 타입의 바인딩 값입니다. TCA에서는 이 값을 **상태(State)**와 **액션(Action)**에 연결하여 관리하게 됩니다.
- 3. titleVisibility (Visibility): 타이틀 영역의 표시 여부를 설정합니다. (.visible, .hidden, .automatic 중 선택 가능합니다.)
- 4. actions (() -> View): 액션 시트 내에 표시될 버튼들을 생성하는 클로저입니다.
액션만약 여러분의 store에 리스트 형태의 데이터를 가지고 있고, 이를 활용하여 액션 시트 버튼을 동적으로 생성하고 싶다면 **ForEach**를 사용해야 합니다.이때 Perception 프레임워크와의 호환성을 위해 **WithPerceptionTracking**으로 감싸주어야 합니다. (이를 생략하면 런타임 에러가 발생할 수 있습니다.)예시 (actions 클로저 내 ForEach 사용):actions: { ForEach(store.domainList, id:\\.self) { domain in WithPerceptionTracking { Button(action: { store.send(.selectEmailDomain(domain)) }) { Text(domain) } } } }
각 버튼에는 원하는 액션을 할당하여 동작을 정의할 수 있습니다. (액션 구현은 아래에서 자세히 설명합니다.)다음으로, **액션 시트의 표시 상태를 관리하는 바인딩(isPresented)**을 구현하는 방법을 알아보겠습니다.TCA 바인딩 구현: isPresented 연결하기
**confirmationDialog**의 isPresented 인자를 효과적으로 사용하기 위해서는 두 가지 핵심 요소가 필요합니다.- 1. 리듀서(Reducer) 내 Bool 타입의 상태(State): 액션 시트의 현재 표시 상태를 저장합니다.
- 2. Bool 값을 전달할 액션(Action): 액션 시트의 상태를 변경할 때 사용됩니다.
예시 코드 (Action 및 State 정의):
enum Action { case presentActionSheet(Bool) } @ObservableState struct State: Equatable { var presentActionSheet: Bool = false }
위 코드에서는 presentActionSheet라는 이름의 액션과 상태를 정의했습니다.이제 이 액션과 상태를 **리듀서의 바디(body)**에 연결하여, 액션이 발생할 때 상태가 변경되도록 구현합니다.예시 코드 (Reducer 내 상태 변경 로직):// reducer case let .presentActionSheet(isPresent): state.presentActionSheet = isPresent
이렇게 정의된 **상태(state.presentActionSheet)**와 **액션(presentActionSheet)**을 **confirmationDialog**의 isPresented 인자에 연결합니다.**isPresented**에 바인딩하는 현대적인 TCA 방식은 다음과 같습니다.isPresented: $store.presentActionSheet.sending(\.presentActionSheet)
이 구문이 처음에는 다소 복잡해 보일 수 있습니다. 이해를 돕기 위해, 이 코드가 **Binding**을 수동으로 생성했던 이전 방식과 어떻게 유사한지 살펴보겠습니다.이전 방식의 Binding 구현 예시:isPresented: Binding( get: { store.presentActionSheet }, set: { isPresented in if isPresented { store.send(.showActionSheet) } else { store.send(.hideActionSheet) } } )
이전 방식에서는 get 클로저에 **액션 시트의 표시 상태(store.presentActionSheet)**를 직접 넣고, set 클로저에서는 액션 시트로부터 전달받은 Bool 값(isPresented)을 기반으로 특정 **액션(showActionSheet 또는 hideActionSheet)**을 store에 send 해주었습니다.새로운 $store.presentActionSheet.sending(\.presentActionSheet) 방식은 이 과정을 더욱 간결하게 표현한 것입니다.store.presentActionSheet에서 **값을 get**하고, **sending(\.presentActionSheet)**를 통해 액션 시트에서 발생한 **Bool 값 변화를 presentActionSheet 액션으로 set**해주는 역할을 합니다.confirmationDialog 전체 코드 예시:.confirmationDialog( Localized.actionSheetTitle, isPresented: $store.presentActionSheet.sending(\\.presentActionSheet), titleVisibility: .visible, actions: { ForEach(store.domainList, id:\\.self) { domain in WithPerceptionTracking { Button(action: { store.send(.selectEmailDomain(domain)) }) { Text(domain) } } } } )
이 코드를 통해 SwiftUI와 TCA를 사용하여 **confirmationDialog**를 활용한 액션 시트를 성공적으로 구현할 수 있습니다.사용자 경험을 향상시키는 데 이 가이드가 도움이 되었기를 바랍니다.SwiftUI + TCA: 실전 프로젝트로 완성하는 차세대 iOS 아키텍처 강의 | 덤벨로퍼 - 인프런
덤벨로퍼 | 복잡한 SwiftUI 상태 관리, TCA (The Composable Architecture)로 깔끔하고 견고한 앱을 만드세요. 실전 프로젝트 예제로 핵심만 빠르게 배웁니다. , SwiftUI + TCA: 실전 프로젝트로 완성하는 차세대
www.inflearn.com
반응형'개발 > Swift' 카테고리의 다른 글
[Swift] 페이지처럼 넘어가는 스크롤 레이아웃 (Carousel Effect) (0) 2025.02.26 [Swift] 애니메이션 동작시 터치 이벤트가 동작 안하는 이유 (0) 2025.02.26 [SwiftUI + TCA] 에러 Perceptible state was accessed but is not being tracked (0) 2025.02.07 TCA에서 AsyncStream 사용해서 타이머 구현하기 (0) 2025.01.15 [Tuist] 모듈 생성 및 테스트 환경 구축 (0) 2025.01.14