apple/TCA

[TCA] FocusState

lgvv 2023. 9. 27. 02:21

[TCA] FocusState

 

TCA의 FocusState 사용방법 정리

 

- 목차

 - FocusState 사용 예제

 

 - FocusState 사용 예제

SwiftUI의 @FocusState는 TCA 라이브러리의 `bind` view Modifier를 통해 사용

 

- 자세한 부분은 코드의 주석을 확인

 

// MARK: - Feature domain

struct FocusDemo: Reducer {
    struct State: Equatable {
        @BindingState var focusedField: Field? // ✅ 2. 포커스 스테이트로 사용할 bindingState를 선언
        @BindingState var password: String = ""
        @BindingState var username: String = ""
        
        enum Field: String, Hashable {
            // ✅ 1. TextField에서 사용할 값을 enum으로 State안에 선언
            case username, password
        }
    }
    
    enum Action: BindableAction, Equatable {
        case binding(BindingAction<State>)
        case signInButtonTapped
    }
    
    var body: some Reducer<State, Action> {
        BindingReducer()
        Reduce { state, action in
            switch action {
            case .binding:
                return .none
                
            case .signInButtonTapped:
                if state.username.isEmpty {
                    state.focusedField = .username
                } else if state.password.isEmpty {
                    state.focusedField = .password
                }
                return .none
            }
        }
    }
}

// MARK: - Feature view

struct FocusDemoView: View {
    let store: StoreOf<FocusDemo>
    @FocusState var focusedField: FocusDemo.State.Field?
    
    var body: some View {
        WithViewStore(self.store, observe: { $0 }) { viewStore in
            Form {
                AboutView(readMe: readMe)
                
                VStack {
                    TextField("Username", text: viewStore.$username)
                        .focused($focusedField, equals: .username)
                    SecureField("Password", text: viewStore.$password)
                        .focused($focusedField, equals: .password)
                    Button("Sign In") {
                        viewStore.send(.signInButtonTapped)
                    }
                    .buttonStyle(.borderedProminent)
                }
                .textFieldStyle(.roundedBorder)
            }
            .bind(viewStore.$focusedField, to: self.$focusedField) // ✅ 3. store와 view의 focus state를 동기화
        }
        .navigationTitle("Focus demo")
    }
}

// MARK: - SwiftUI previews

struct FocusDemo_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            FocusDemoView(
                store: Store(initialState: FocusDemo.State()) {
                    FocusDemo()
                }
            )
        }
    }
}

 

 

(참고)

https://github.com/pointfreeco/swift-composable-architecture/blob/main/Examples/CaseStudies/SwiftUICaseStudies/01-GettingStarted-FocusState.swift

 

 

'apple > TCA' 카테고리의 다른 글

[TCA] SharedState  (1) 2023.09.27
[TCA] OptionalState (IfLetCase)  (0) 2023.09.27
[TCA] Binding  (0) 2023.09.27
[TCA] Tutorial #5 (Multiple presentation destinations)  (0) 2023.09.24
[TCA] 공부기록 #1 (ReducerProtocol)  (0) 2023.01.16