ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TCA] ScrollToTop
    Swift/TCA 2023. 12. 24. 21:39
    struct ContentView: View {
        
        @State var store = Store(initialState: Content.State()) {
            Content()
        }
        
        var body: some View {
            WithViewStore(store, observe: { $0 }) { viewStore in
                VStack(spacing: 0) {
                    ScrollViewReader(content: { proxy in
                        ScrollView {
                            LazyVStack {
                                
                                Color.clear.frame(height: 0)
                                    .id("Top")
                                
                                ForEach(viewStore.items, id: \.self) { int in
                                    Text(String(int))
                                        .frame(height: 80)
                                }
                            }
                        }
                        .onReceive(store.publisher.shouldScrollToTop, perform: { value in
                            guard value else { return }
                            withAnimation {
                                proxy.scrollTo("Top")
                            }
                        })
                        
                    })
                    Button(action: {
                        store.send(.didTapBottomButton)
                    }, label: {
                        Text("Button")
                            .frame(maxWidth: .infinity)
                            .frame(height: 80)
                            .background(Color.gray.opacity(0.6))
                            .foregroundStyle(Color.white)
                            .font(.title.bold())
                    })
                }
                .overlay(content: {
                    if viewStore.items.isEmpty {
                        ProgressView()
                            .scaleEffect(1.5)
                    }
                })
                .onAppear { viewStore.send(.onAppear) }
            }
        }
    }
    
    @Reducer
    struct Content {
        
        struct State: Equatable {
            var items: [Int] = []
            var shouldScrollToTop = false
        }
    
        enum Action {
            case onAppear,
                 fetchItems,
                 didTapBottomButton,
                 didScrollToTop
        }
        
        @Dependency(\.continuousClock) var clock
        
        var body: some Reducer<State, Action> {
            Reduce { state, action in
                switch action {
                    
                case .onAppear:
                    return .run { send in
                        try await clock.sleep(for: .seconds(3))
                        await send(.fetchItems)
                    }
                    
                case .fetchItems:
                    state.items = Array(0...50)
                    return .none
                    
                case .didTapBottomButton:
                    state.shouldScrollToTop = true
                    return .run { send in
                        await send(.didScrollToTop)
                    }
                    
                case .didScrollToTop:
                    state.shouldScrollToTop = false
                    return .none
                }
            }
        }
    }

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

    [TCA] Throttle, Debounce  (0) 2023.12.24
Designed by Tistory.