💡
SwiftUI Idea - Bindingを発行するcomponent
- Bindingを求めるコンポーネントがある
- Bindingを発行するには主にStateが必要
- 簡単な方法はwrapperとなるviewを作りそこにStateを持たせること
- ユースケースが単純であれば一般化したコンポーネントにしてwrapperの作成を省略できる
- LocalStateとして一般化されたコンポーネントを実装する
Example
struct ComponentState: Equatable {
var a = "1"
var b = "2"
var c = "3"
}
var body: some View {
VStack {
LocalState(
initial: ComponentState(),
onChange: { print($0) }
) { state in
TextField("A", text: state.a)
TextField("B", text: state.b)
TextField("C", text: state.c)
}
}
}
Implementation
public struct LocalState<State: Equatable, Content: View>: View {
@SwiftUI.State var state: State
private let content: (Binding<State>) -> Content
private let onChange: (State) -> Void
public init(
initial: State,
onChange: @escaping (State) -> Void = { _ in },
@ViewBuilder content: @escaping (Binding<State>) -> Content
) {
self.onChange = onChange
self._state = .init(initialValue: initial)
self.content = content
}
public var body: some View {
content($state)
.onChange(of: state) { newValue in
onChange(newValue)
}
}
}
Discussion