mastodon-ios/Mastodon/Protocol/LoadMoreConfigurableTableVi...

50 lines
2.0 KiB
Swift

//
// LoadMoreConfigurableTableViewContainer.swift
// Mastodon
//
// Created by sxiaojian on 2021/2/3.
//
import UIKit
import GameplayKit
/// The tableView container driven by state machines with "LoadMore" logic
protocol LoadMoreConfigurableTableViewContainer: UIViewController {
associatedtype BottomLoaderTableViewCell: UITableViewCell
associatedtype LoadingState: GKState
var loadMoreConfigurableTableView: UITableView { get }
var loadMoreConfigurableStateMachine: GKStateMachine { get }
func handleScrollViewDidScroll(_ scrollView: UIScrollView)
}
extension LoadMoreConfigurableTableViewContainer {
func handleScrollViewDidScroll(_ scrollView: UIScrollView) {
guard scrollView === loadMoreConfigurableTableView else { return }
// check if current scroll position is the bottom of table
let contentOffsetY = loadMoreConfigurableTableView.contentOffset.y
let bottomVisiblePageContentOffsetY = loadMoreConfigurableTableView.contentSize.height - (1.5 * loadMoreConfigurableTableView.visibleSize.height)
guard contentOffsetY > bottomVisiblePageContentOffsetY else {
return
}
let cells = loadMoreConfigurableTableView.visibleCells.compactMap { $0 as? BottomLoaderTableViewCell }
guard let loaderTableViewCell = cells.first else { return }
if let tabBar = tabBarController?.tabBar, let window = view.window {
let loaderTableViewCellFrameInWindow = loadMoreConfigurableTableView.convert(loaderTableViewCell.frame, to: nil)
let windowHeight = window.frame.height
let loaderAppear = (loaderTableViewCellFrameInWindow.origin.y + 0.8 * loaderTableViewCell.frame.height) < (windowHeight - tabBar.frame.height)
if loaderAppear {
loadMoreConfigurableStateMachine.enter(LoadingState.self)
} else {
// do nothing
}
} else {
loadMoreConfigurableStateMachine.enter(LoadingState.self)
}
}
}