✅ 기존 TCA에서 TabView를 사용한 자료들은 TCA viewStore을 사용한 예제만 존재함. (구 버전...)
viewStore를 쓰지 않고 Bindable을 사용한 TCA에서 TabView를 어떻게 자연스럽게 쓸 수 있을까??
✅ TCA 버전 1.9.2
문제점
❗ 타이머 뷰에서 타이머 작동 후, 탭을 스와이프 한 후 돌아오니 타이머 뷰가 사라지는 문제점 발생

원인: TabView Swipe 할 때 마다 새로운 Store을 생성하는 하위 뷰

- Swipe 후, 기존 TimerFeature 내부 타이머 뿐만 아니라 새로운 TimerFeature 내부 타이머도 호출되는 것을 발견
TabView와 연결된 상위 Feature에서 하위 Feature인 TimerFeature의 값을 전파해서 문제를 해결해야겠다고 생각함
해결법: Scope를 이용해 하위 도메인 값 넘기기
1. store.scope를 통한 하위 뷰 store 생성
import SwiftUI
import ComposableArchitecture
struct DoroMainView: View {
@Perception.Bindable var store: StoreOf<Feature>
var body: some View {
WithPerceptionTracking {
TabView(selection: $store.pageSelection.sending(\.pageMove), content: {
AnalyzeView(store: self.store.scope(state: \.anylzeState, action: \.analyze))
.tag(DorocatFeature.PageType.analyze)
TimerView(store: store.scope(state: \.timerState, action: \.timer))
.tag(DorocatFeature.PageType.timer)
SettingView(store: self.store.scope(state: \.settingState, action: \.setting))
.tag(DorocatFeature.PageType.setting)
})
.tabViewStyle(.page(indexDisplayMode: .never))
}
}
}
2. Scope 컴포넌트를 이용한 하위 Feature 생성
2-1. 상위 State에 TabView 하위 뷰에서 사용할 State들 생성
@Reducer struct Feature{
...
@ObservableState struct State: Equatable{
var pageSelection: PageType = .timer
var anylzeState = AnalyzeFeature.State()
var timerState = TimerFeature.State()
var settingState = SettingFeature.State()
}
...
}
2-2. 상위 Action에 TabView 하위 뷰에서 사용할 Action들 생성
@Reducer struct Feature{
...
enum Action:Equatable{
case pageMove(PageType)
case timer(TimerFeature.Action)
case analyze(AnalyzeFeature.Action)
case setting(SettingFeature.Action)
}
...
}
2-3. ⭐ Scope 컴포넌트를 이용해 하위 Feature 생성
@Reducer struct Feature{
...
var body: some ReducerOf<Self>{
Reduce{ state, action in
...
}
Scope(state: \.timerState, action: /DorocatFeature.Action.timer) {
TimerFeature()
}
...
}
...
}
결과
TabView Swipe 후에도 하나의 State만 갖고 있어 타이머가 잘 작동하는 것을 볼 수 있다!!

'이모저모 > SwiftUI' 카테고리의 다른 글
TCA - 뽀모도로 앱, Timer View Interaction (0) | 2024.05.07 |
---|---|
TCA에서 Stream 생성 및 주입 (0) | 2024.04.13 |
Using @globalActor RealmSwift in TCA (0) | 2024.03.25 |
웹 통신과 ObservedObject, StateObject (0) | 2024.02.20 |
Present, FullScreen 한 번에 처리하기 (0) | 2023.12.12 |
댓글