0
0

More than 1 year has passed since last update.

TCAのReducerからスクロール位置を変更する

Last updated at Posted at 2021-10-05

概要

TCAのReducerからスクロールビューのスクロール位置の操作をする方法がわからなかったのですが、NotificationCenterを使ったら出来ました。
他にもっと良い方法はあるかもしれません。

ソースコード

github: https://github.com/k-yamada/TCAScrollFromReducer

NSNotification+.swift
extension NSNotification {
    static let scrollUp = Notification.Name.init("scrollUp")
    static let scrollDown = Notification.Name.init("scrollDown")
}
AppView.swift
struct AppView: View {
    let store: Store<AppState, AppAction>
    let items = (1...100)

    var body: some View {
        WithViewStore(store) { viewStore in
            ScrollViewReader { scrollProxy in
                ZStack {
                    ScrollView {
                        ForEach(items, id: \.self) { Text("\($0)"); Divider() }
                    }
                    .onReceive(NotificationCenter.default.publisher(for: NSNotification.scrollUp)) { _ in
                        scrollProxy.scrollTo(items.first!)
                    }
                    .onReceive(NotificationCenter.default.publisher(for: NSNotification.scrollDown)) { _ in
                        scrollProxy.scrollTo(items.last!)
                    }
                    VStack {
                        Spacer()
                        HStack {
                            Button("Up") {
                                viewStore.send(.upButtonTapped)
                            }
                            Spacer()
                            Button("Down") {
                                viewStore.send(.downButtonTapped)
                            }
                        }
                    }.padding(EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20))
                }
            }
        }
    }
}
AppCore.swift
import ComposableArchitecture
import SwiftUI

struct AppState: Equatable {
}

enum AppAction: Equatable {
    case upButtonTapped
    case downButtonTapped
}

struct AppEnvironment {
    var mainQueue: AnySchedulerOf<DispatchQueue>
}

let appReducer = Reducer<AppState, AppAction, AppEnvironment> { state, action, environment in
    switch action {
    case .upButtonTapped:
        NotificationCenter.default.post(name: NSNotification.scrollUp, object: nil, userInfo: nil)
        return .none
    case .downButtonTapped:
        NotificationCenter.default.post(name: NSNotification.scrollDown, object: nil, userInfo: nil)
        return .none
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0