diff --git a/Sources/Classes/Pagination/PaginationTableViewWrapper.swift b/Sources/Classes/Pagination/PaginationTableViewWrapper.swift index e0b2e591..81f04a0a 100644 --- a/Sources/Classes/Pagination/PaginationTableViewWrapper.swift +++ b/Sources/Classes/Pagination/PaginationTableViewWrapper.swift @@ -209,7 +209,7 @@ where Delegate.Cursor == Cursor { tableView.support.refreshControl?.endRefreshing() - if !(cursor is SingleLoadCursor) { + if !cursor.exhausted { addInfiniteScroll() } } else if case .loadingMore = afterState { @@ -260,14 +260,33 @@ where Delegate.Cursor == Cursor { replacePlaceholderViewIfNeeded(with: emptyView) } - private func replacePlaceholderViewIfNeeded(with view: UIView) { + private func replacePlaceholderViewIfNeeded(with placeholderView: UIView) { // don't update placeholder view if previous placeholder is the same one - if currentPlaceholderView === view { + if currentPlaceholderView === placeholderView { return } - enterPlaceholderState() - preparePlaceholderView(view) - currentPlaceholderView = view + tableView.isUserInteractionEnabled = true + removeCurrentPlaceholderView() + + placeholderView.translatesAutoresizingMaskIntoConstraints = false + placeholderView.isHidden = false + + // I was unable to add pull-to-refresh placeholder scroll behaviour without this trick + let wrapperView = UIView() + wrapperView.addSubview(placeholderView) + + let leadingConstraint = placeholderView.leadingAnchor.constraint(equalTo: wrapperView.leadingAnchor) + let trailingConstraint = placeholderView.trailingAnchor.constraint(equalTo: wrapperView.trailingAnchor) + let topConstraint = placeholderView.topAnchor.constraint(equalTo: wrapperView.topAnchor) + let bottomConstraint = placeholderView.bottomAnchor.constraint(equalTo: wrapperView.bottomAnchor) + + wrapperView.addConstraints([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint]) + + currentPlaceholderViewTopConstraint = topConstraint + + tableView.backgroundView = wrapperView + + currentPlaceholderView = placeholderView } // MARK: - private stuff @@ -336,32 +355,6 @@ where Delegate.Cursor == Cursor { .addDisposableTo(disposeBag) } - private func enterPlaceholderState() { - tableView.isUserInteractionEnabled = true - - removeCurrentPlaceholderView() - } - - private func preparePlaceholderView(_ placeholderView: UIView) { - placeholderView.translatesAutoresizingMaskIntoConstraints = false - placeholderView.isHidden = false - - // I was unable to add pull-to-refresh placeholder scroll behaviour without this trick - let wrapperView = UIView() - wrapperView.addSubview(placeholderView) - - let leadingConstraint = placeholderView.leadingAnchor.constraint(equalTo: wrapperView.leadingAnchor) - let trailingConstraint = placeholderView.trailingAnchor.constraint(equalTo: wrapperView.trailingAnchor) - let topConstraint = placeholderView.topAnchor.constraint(equalTo: wrapperView.topAnchor) - let bottomConstraint = placeholderView.bottomAnchor.constraint(equalTo: wrapperView.bottomAnchor) - - wrapperView.addConstraints([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint]) - - currentPlaceholderViewTopConstraint = topConstraint - - tableView.backgroundView = wrapperView - } - private func removeCurrentPlaceholderView() { tableView.backgroundView = nil } diff --git a/Sources/Classes/Pagination/PaginationViewModel.swift b/Sources/Classes/Pagination/PaginationViewModel.swift index d5de6da9..75407802 100644 --- a/Sources/Classes/Pagination/PaginationViewModel.swift +++ b/Sources/Classes/Pagination/PaginationViewModel.swift @@ -61,13 +61,11 @@ public final class PaginationViewModel { /// /// - reload: reload all items and reset cursor to initial state. /// - next: load next batch of items. + /// - retry: reload to initial loading state public enum LoadType { - /// pull-to-refresh case reload - /// retry button inside placeholder case retry - case next } diff --git a/Sources/Protocols/LoadingIndicator.swift b/Sources/Protocols/LoadingIndicator.swift index d1735dc2..24cc2af5 100644 --- a/Sources/Protocols/LoadingIndicator.swift +++ b/Sources/Protocols/LoadingIndicator.swift @@ -22,6 +22,18 @@ import UIKit +/// Protocol that describes placeholder view, containing loading indicator. +public protocol LoadingIndicatorHolder: class { + var loadingIndicator: Animatable { get } + var indicatorOwner: UIView { get } +} + +public extension LoadingIndicatorHolder where Self: UIView { + public var indicatorOwner: UIView { + return self + } +} + /// Protocol that describes badic loading indicator. public protocol LoadingIndicator { diff --git a/Sources/Structures/Views/AnyLoadingIndicator.swift b/Sources/Structures/Views/AnyLoadingIndicator.swift index ebdf7422..fd2b4a63 100644 --- a/Sources/Structures/Views/AnyLoadingIndicator.swift +++ b/Sources/Structures/Views/AnyLoadingIndicator.swift @@ -25,20 +25,28 @@ import UIKit /// Type that performs some kind of type erasure for LoadingIndicator. public struct AnyLoadingIndicator: Animatable { - private let internalView: UIView + private let backgroundView: UIView private let animatableView: Animatable /// Initializer with indicator that should be wrapped. /// /// - Parameter _: indicator for wrapping. - public init (_ base: Indicator, backgroundView: UIView? = nil) where Indicator: LoadingIndicator { - self.internalView = backgroundView ?? base.view + public init (_ base: Indicator) where Indicator: LoadingIndicator { + self.backgroundView = base.view self.animatableView = base.view } - /// The indicator view. + /// Initializer with placeholder view, that wraps indicator. + /// + /// - Parameter loadingIndicatorHolder: placeholder view, containing indicator. + public init(loadingIndicatorHolder: LoadingIndicatorHolder) { + self.backgroundView = loadingIndicatorHolder.indicatorOwner + self.animatableView = loadingIndicatorHolder.loadingIndicator + } + + /// The background view. var view: UIView { - return internalView + return backgroundView } public func startAnimating() {