はじめに
こんにちは!
アプリ開発が好きで、Swiftの勉強をしている大学生です。
温かい目で見ていただけると幸いです。
やりたいこと
インターン先でTCAを使ったプロジェクトに関わっているため、TCAの勉強をしています。
そのため、以前に投稿した下記のSideMenuView
をTCAで実装してみました。
実装
まずはReducer
の実装です。
public struct HogeReducer: Reducer {
// MARK: - State
public struct State: Equatable {
var offset: CGFloat = 0
var screenSizeWidth: CGFloat = 0
var sideBarWidth: CGFloat = 0
var showSideBar: Bool = false
}
// MARK: - Action
public enum Action: Equatable {
case viewAppeared(CGFloat)
case changeShowSideBar(CGFloat)
case sideMenuButtonTapped
case rectangleTapped
}
// MARK: - Dependencies
public init() {}
// MARK: - Reducer
public func reduce(into state: inout State, action: Action) -> Effect<Action> {
switch action {
case let .changeShowSideBar(size):
if state.showSideBar && state.offset == 0 {
state.offset = size - 90
}
if !state.showSideBar && state.offset == size - 90 {
state.offset = 0
}
return .none
case let .viewAppeared(size):
state.screenSizeWidth = size
state.sideBarWidth = size - 90
return .none
case .sideMenuButtonTapped:
state.showSideBar.toggle()
return .none
case .rectangleTapped:
state.showSideBar.toggle()
return .none
}
}
}
続いてViewの実装です。
public struct HogeView: View {
@ObservedObject private var viewStore: ViewStoreOf<HogeReducer>
let store: StoreOf<HogeReducer>
public init(store: StoreOf<HogeReducer>) {
self.store = store
self.viewStore = ViewStore(store, observe: { $0 })
}
public var body: some View {
HStack(spacing: 0) {
SideMenuView()
VStack {
Button("SideMenuView") {
viewStore.send(.sideMenuButtonTapped)
}
}
.frame(width: viewStore.screenSizeWidth)
.frame(maxHeight: .infinity)
.overlay {
Rectangle()
.fill(
Color.primary
.opacity(Double((viewStore.offset / (viewStore.screenSizeWidth - 90) ) / 5))
)
.ignoresSafeArea(.container, edges: .vertical)
.onTapGesture {
viewStore.send(.rectangleTapped)
}
}
}
.frame(width: viewStore.screenSizeWidth + viewStore.sideBarWidth)
.offset(x: -viewStore.sideBarWidth / 2)
.offset(x: viewStore.offset > 0 ? viewStore.offset : 0)
.onChange(of: viewStore.showSideBar) { _ in
viewStore.send(.changeShowSideBar(getScreenRect()), animation: .default)
}
.onAppear {
viewStore.send(.viewAppeared(getScreenRect()))
}
}
}
これで実装できました!
TCA慣れるまでかなり時間かかりそうです...
終わりに
誰かの役に立つことができていれば幸いです。
アウトプットを頑張ろうと思っているので温かい目で見ていただけると嬉しいです。