88
99import SwiftUI
1010
11+ public extension CGFloat {
12+ static let bb_invalidBottomSpaceForLoadingMore = CGFloat . greatestFiniteMagnitude
13+ }
14+
1115public extension BBTableView {
1216 func bb_reloadData( _ reloadData: Binding < Bool > ) -> Self {
1317 var view = self
@@ -45,12 +49,19 @@ public extension BBTableView {
4549 return view
4650 }
4751
48- func bb_pullDownToRefresh( _ isRefreshing: Binding < Bool > , refresh: @escaping ( ) -> Void ) -> Self {
52+ func bb_pullDownToRefresh( isRefreshing: Binding < Bool > , refresh: @escaping ( ) -> Void ) -> Self {
4953 var view = self
5054 view. _isRefreshing = isRefreshing
5155 view. pullDownToRefresh = refresh
5256 return view
5357 }
58+
59+ func bb_pullUpToLoadMore( bottomSpace: CGFloat , loadMore: @escaping ( ) -> Void ) -> Self {
60+ var view = self
61+ view. bottomSpaceForLoadingMore = bottomSpace
62+ view. pullUpToLoadMore = loadMore
63+ return view
64+ }
5465}
5566
5667public struct BBTableViewScrollToRowParameter {
@@ -84,6 +95,8 @@ public struct BBTableView<Data, Content>: UIViewControllerRepresentable, BBUIScr
8495 @Binding public var isRefreshing : Bool
8596 public var setupRefreshControl : ( ( UIRefreshControl ) -> Void ) ?
8697 public var pullDownToRefresh : ( ( ) -> Void ) ?
98+ public var bottomSpaceForLoadingMore : CGFloat
99+ public var pullUpToLoadMore : ( ( ) -> Void ) ?
87100
88101 public init ( _ data: Data ,
89102 reloadData: Binding < Bool > = . constant( false ) ,
@@ -100,6 +113,8 @@ public struct BBTableView<Data, Content>: UIViewControllerRepresentable, BBUIScr
100113 isRefreshing: Binding < Bool > = . constant( false ) ,
101114 setupRefreshControl: ( ( UIRefreshControl ) -> Void ) ? = nil ,
102115 pullDownToRefresh: ( ( ) -> Void ) ? = nil ,
116+ bottomSpaceForLoadingMore: CGFloat = . bb_invalidBottomSpaceForLoadingMore,
117+ pullUpToLoadMore: ( ( ) -> Void ) ? = nil ,
103118 @ViewBuilder content: @escaping ( Data . Element ) -> Content )
104119 {
105120 self . data = data
@@ -118,6 +133,8 @@ public struct BBTableView<Data, Content>: UIViewControllerRepresentable, BBUIScr
118133 self . _isRefreshing = isRefreshing
119134 self . setupRefreshControl = setupRefreshControl
120135 self . pullDownToRefresh = pullDownToRefresh
136+ self . bottomSpaceForLoadingMore = bottomSpaceForLoadingMore
137+ self . pullUpToLoadMore = pullUpToLoadMore
121138 }
122139
123140 public func makeUIViewController( context: Context ) -> UIViewController {
@@ -165,7 +182,7 @@ private class _BBTableViewController<Data, Content>: UIViewController, UITableVi
165182 tableView. refreshControl = refreshControl
166183 }
167184
168- // TODO: Detect content offset to bottom space and load more data
185+ // TODO: Refresh when first will appear
169186
170187 NSLayoutConstraint . activate ( [
171188 view. leftAnchor. constraint ( equalTo: tableView. leftAnchor) ,
@@ -264,6 +281,14 @@ private class _BBTableViewController<Data, Content>: UIViewController, UITableVi
264281 DispatchQueue . main. async { [ weak self] in
265282 guard let self = self else { return }
266283 self . representable. contentOffset = scrollView. contentOffset
284+
285+ if self . representable. bottomSpaceForLoadingMore != . bb_invalidBottomSpaceForLoadingMore,
286+ let loadMore = self . representable. pullUpToLoadMore {
287+ let space = scrollView. contentSize. height - scrollView. contentOffset. y - scrollView. frame. height
288+ if space <= self . representable. bottomSpaceForLoadingMore {
289+ loadMore ( )
290+ }
291+ }
267292 }
268293 }
269294}
0 commit comments