UITableView 分页 - 底部刷新以在 Swift 中加载新数据
UITableView Pagination - Bottom Refresh to Load New Data in Swift
我正在尝试通过分页实现从我的后端加载数据。我已经看到了这个,但是它一直加载所有数据。这是正确的方法还是我做错了什么?
提前致谢。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
print(indexPath.row)
if (indexPath.row + 1 < self.TotalRowsWithPages) {
cell.textLabel?.text = "\(self.myarray!.[indexPath.row].body)"
} else {
cell.textLabel?.text = "Loading more data...";
// User has scrolled to the bottom of the list of available data so simulate loading some more if we aren't already
if (!self.isLoading) {
self.isLoading = true;
self.TotalRowsWithPages = self.TotalRowsWithPages + self.PageSize
self.getmoredata()
}
}
return cell
}
尝试检查更多数据,而不是在 cellForRowAtIndexPath 中,而是在 UIScrollViewDelegate 中 - [DataModel sharedMyLibrary] 是我的数据源 class 使用 RESTful API 加载视频数据和分页,它是 fetchWithCompletion 方法从服务器异步获取数据,它的 hasMore 方法表示服务器有更多数据(JSON 包含下一个 link) LibraryTableViewController - 是 UITableViewController 的子class,hasMore - 是视图故事板中 table 视图的底部包含一个按钮,因此用户有两个选择:向下滚动或按下按钮。此外,如果此视图可见,则表示服务器上有更多数据。 _canFetch 防止从服务器嵌套加载。
``
@interface LibraryTableViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIView *hasMore;
@end
@implementation LibraryTableViewController
{
__block volatile uint8_t _canFetch;
}
@synthesize hasMore = _hasMore;
- (void)viewDidLoad
{
_canFetch = 0x80;
[super viewDidLoad];
[self fetchVideos:NO];
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
CGPoint offset = [scrollView contentOffset];
if ([[DataModel sharedMyLibrary] hasMore])
{
if (((velocity.y > 0.0) && (offset.y > (*targetContentOffset).y)) || ((velocity.x > 0.0) && (offset.x > (*targetContentOffset).x)))
{
[self fetchVideos:NO];
}
}
else
{
[_hasMore setHidden:YES];
}
}
- (IBAction)moreVideos:(UIButton *)sender
{
[self fetchVideos:NO];
}
- (IBAction)doRefresh:(UIRefreshControl *)sender
{
[sender endRefreshing];
[[DataModel sharedMyLibrary] clear];
[self fetchVideos:YES];
}
- (void)fetchVideos:(BOOL)reload
{
if (OSAtomicTestAndClear(0, &(_canFetch)))
{
__weak typeof(self) weakSelf = self;
[[DataModel sharedMyLibrary] fetchWithCompletion:^(NSArray *indexPathes) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(self) strongSelf = weakSelf;
if (indexPathes != nil)
{
if (reload)
{
[[strongSelf tableView] reloadData];
}
else
{
[[strongSelf tableView] beginUpdates];
[[strongSelf tableView] insertRowsAtIndexPaths:indexPathes withRowAnimation:UITableViewRowAnimationAutomatic];
[[strongSelf tableView] endUpdates];
}
}
else
{
[[strongSelf tableView] reloadData];
}
[strongSelf->_hasMore setHidden:![[DataModel sharedMyLibrary] hasMore]];
strongSelf->_canFetch = 0x80;
});
}];
}
}
``
您应该在 tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
中实现加载更多。当显示最后一个单元格加载时,这意味着用户滚动到底部,所以这是您需要加载更多数据的时候。
也许看起来像这样:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if !(indexPath.row + 1 < self.TotalRowsWithPages) {
self.isLoading = true;
self.getmoredata()
}
}
不,你不能采用这种方法,因为 cellForRowAtIndexPath
被调用了很多次,而且检查你的条件会花费很多时间!
在这里,我找到了一个更好的 UITableView
分页选项。
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
//Bottom Refresh
if scrollView == tableView{
if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height)
{
if !isNewDataLoading{
if helperInstance.isConnectedToNetwork(){
isNewDataLoading = true
getNewData()
}
}
}
}
}
isNewDataLoading
是 Bool
检查 UITableView
是否正在加载新数据!
希望对您有所帮助!
我正在尝试通过分页实现从我的后端加载数据。我已经看到了这个,但是它一直加载所有数据。这是正确的方法还是我做错了什么?
提前致谢。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
print(indexPath.row)
if (indexPath.row + 1 < self.TotalRowsWithPages) {
cell.textLabel?.text = "\(self.myarray!.[indexPath.row].body)"
} else {
cell.textLabel?.text = "Loading more data...";
// User has scrolled to the bottom of the list of available data so simulate loading some more if we aren't already
if (!self.isLoading) {
self.isLoading = true;
self.TotalRowsWithPages = self.TotalRowsWithPages + self.PageSize
self.getmoredata()
}
}
return cell
}
尝试检查更多数据,而不是在 cellForRowAtIndexPath 中,而是在 UIScrollViewDelegate 中 - [DataModel sharedMyLibrary] 是我的数据源 class 使用 RESTful API 加载视频数据和分页,它是 fetchWithCompletion 方法从服务器异步获取数据,它的 hasMore 方法表示服务器有更多数据(JSON 包含下一个 link) LibraryTableViewController - 是 UITableViewController 的子class,hasMore - 是视图故事板中 table 视图的底部包含一个按钮,因此用户有两个选择:向下滚动或按下按钮。此外,如果此视图可见,则表示服务器上有更多数据。 _canFetch 防止从服务器嵌套加载。
``
@interface LibraryTableViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIView *hasMore;
@end
@implementation LibraryTableViewController
{
__block volatile uint8_t _canFetch;
}
@synthesize hasMore = _hasMore;
- (void)viewDidLoad
{
_canFetch = 0x80;
[super viewDidLoad];
[self fetchVideos:NO];
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
CGPoint offset = [scrollView contentOffset];
if ([[DataModel sharedMyLibrary] hasMore])
{
if (((velocity.y > 0.0) && (offset.y > (*targetContentOffset).y)) || ((velocity.x > 0.0) && (offset.x > (*targetContentOffset).x)))
{
[self fetchVideos:NO];
}
}
else
{
[_hasMore setHidden:YES];
}
}
- (IBAction)moreVideos:(UIButton *)sender
{
[self fetchVideos:NO];
}
- (IBAction)doRefresh:(UIRefreshControl *)sender
{
[sender endRefreshing];
[[DataModel sharedMyLibrary] clear];
[self fetchVideos:YES];
}
- (void)fetchVideos:(BOOL)reload
{
if (OSAtomicTestAndClear(0, &(_canFetch)))
{
__weak typeof(self) weakSelf = self;
[[DataModel sharedMyLibrary] fetchWithCompletion:^(NSArray *indexPathes) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(self) strongSelf = weakSelf;
if (indexPathes != nil)
{
if (reload)
{
[[strongSelf tableView] reloadData];
}
else
{
[[strongSelf tableView] beginUpdates];
[[strongSelf tableView] insertRowsAtIndexPaths:indexPathes withRowAnimation:UITableViewRowAnimationAutomatic];
[[strongSelf tableView] endUpdates];
}
}
else
{
[[strongSelf tableView] reloadData];
}
[strongSelf->_hasMore setHidden:![[DataModel sharedMyLibrary] hasMore]];
strongSelf->_canFetch = 0x80;
});
}];
}
}
``
您应该在 tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
中实现加载更多。当显示最后一个单元格加载时,这意味着用户滚动到底部,所以这是您需要加载更多数据的时候。
也许看起来像这样:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if !(indexPath.row + 1 < self.TotalRowsWithPages) {
self.isLoading = true;
self.getmoredata()
}
}
不,你不能采用这种方法,因为 cellForRowAtIndexPath
被调用了很多次,而且检查你的条件会花费很多时间!
在这里,我找到了一个更好的 UITableView
分页选项。
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
//Bottom Refresh
if scrollView == tableView{
if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height)
{
if !isNewDataLoading{
if helperInstance.isConnectedToNetwork(){
isNewDataLoading = true
getNewData()
}
}
}
}
}
isNewDataLoading
是 Bool
检查 UITableView
是否正在加载新数据!
希望对您有所帮助!