UITableView无限滚动

adi*_*dit 40 iphone objective-c ipad ios

如何进行无限滚动UITableView?我知道如何使用UIScrollView苹果在WWDC的一个视频中演示过.我尝试过以下方面tableView:cellForRowAtIndexPath::

if (indexPath.row == [self.newsFeedData_ count] - 1)
{
    [self.newsFeedData_ addObjectsFromArray:self.newsFeedData_];
    [self.tableView reloadData];
}
Run Code Online (Sandbox Code Playgroud)

但这失败了.还有其他想法吗?

Cod*_*aFi 56

如果您需要知道何时触及UITableView的底部,请成为它的委托(因为它是UIScrollView的子类),并使用-scrollViewDidScroll:委托方法来比较表的内容高度和它的实际滚动位置.

编辑(类似这样):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView_ 
{   
    CGFloat actualPosition = scrollView_.contentOffset.y;
    CGFloat contentHeight = scrollView_.contentSize.height - (someArbitraryNumber);
    if (actualPosition >= contentHeight) {
        [self.newsFeedData_ addObjectsFromArray:self.newsFeedData_];
        [self.tableView reloadData];
     }
}
Run Code Online (Sandbox Code Playgroud)

  • 我用`someArbitraryNumber`作为`tableView.frame.size.height` (9认同)

Ric*_*ung 18

您可以支持无限滚动,使用拉动在顶部刷新和/或使用旋转轮在底部连续滚动:

https://github.com/samvermette/SVPullToRefresh

SVPullToRefreshUITableView到达底部时处理逻辑.自动显示微调器并触发回调块.您将业务逻辑添加到回调块.

这是一个例子:

#import "UIScrollView+SVInfiniteScrolling.h"

// ...

[tableView addInfiniteScrollingWithActionHandler:^{
    // append data to data source, insert new cells at the end of table view
    // call [tableView.infiniteScrollingView stopAnimating] when done
}];
Run Code Online (Sandbox Code Playgroud)

可以使用CocoaPods将此项目添加到项目中,也可以直接编译到项目中.


Oli*_*ain 17

这是一个非常快速和完整的无限滚动UITableView的演示,我把它放在一起......

@interface InfiniteScrollViewController ()

@property (nonatomic) NSMutableArray *tableViewData;
@property (nonatomic) BOOL loadingMoreTableViewData;

@end

@implementation InfiniteScrollViewController

- (void)viewDidLoad {
    self.tableViewData = [[NSMutableArray alloc] init];
    [self addSomeMoreEntriesToTableView];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.tableViewData.count + 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    if (indexPath.row < self.tableViewData.count) {
        cell.textLabel.text = [self.tableViewData objectAtIndex:indexPath.row];
    } 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.loadingMoreTableViewData) {
            self.loadingMoreTableViewData = YES;
            [self performSelector:@selector(addSomeMoreEntriesToTableView) withObject:nil afterDelay:5.0f];
        }
    }

    return cell;
}

- (void)addSomeMoreEntriesToTableView {
    int loopTill = self.tableViewData.count + 20;
    while (self.tableViewData.count < loopTill) {
        [self.tableViewData addObject:[NSString stringWithFormat:@"%i", self.tableViewData.count]];
    };
    self.loadingMoreTableViewData = NO;
    [self.tableView reloadData];
}

@end
Run Code Online (Sandbox Code Playgroud)


Anu*_*tel 12

'UITableView'与'scrollViewDidScroll'方法中的'UIScrollView'相同.

因此,它很容易模拟无限滚动.

  1. 将数组加倍,使头部和尾部连接在一起,以模拟圆形表格

  2. 使用我的以下代码,当用户往往到达表的开头或结尾时,用户在doubled表的1st部分和doubled表的2nd部分之间切换.

:

/* To emulate infinite scrolling...

The table data was doubled to join the head and tail: (suppose table had 1,2,3,4)
1 2 3 4|1 2 3 4 (actual data doubled)
---------------
1 2 3 4 5 6 7 8 (visualising joined table in eight parts)

When the user scrolls backwards to 1/8th of the joined table, user is actually at the 1/4th of actual data, so we scroll instantly (we take user) to the 5/8th of the joined table where the cells are exactly the same.

Similarly, when user scrolls to 6/8th of the table, we will scroll back to 2/8th where the cells are same. (I'm using 6/8th when 7/8th sound more logical because 6/8th is good for small tables.)

In simple words, when user reaches 1/4th of the first half of table, we scroll to 1/4th of the second half, when he reaches 2/4th of the second half of table, we scroll to the 2/4 of first half. This is done simply by subtracting OR adding half the length of the new/joined table.
*/


-(void)scrollViewDidScroll:(UIScrollView *)scrollView_ 
{  

    CGFloat currentOffsetX = scrollView_.contentOffset.x;
    CGFloat currentOffSetY = scrollView_.contentOffset.y;
    CGFloat contentHeight = scrollView_.contentSize.height;

    if (currentOffSetY < (contentHeight / 8.0)) {
    scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY + (contentHeight/2)));
    }
   if (currentOffSetY > ((contentHeight * 6)/ 8.0)) {
       scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY - (contentHeight/2)));
    }

}
Run Code Online (Sandbox Code Playgroud)

PS - 我在我的一个名为NT Time Table(Lite)的应用程序中使用了这段代码.如果您想要预览,可以查看该应用:https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt = 8

如果您的表有时可能太短,则在上述方法的开头,您可以添加if逻辑以在数据计数例如小于9时退出该方法.


zev*_*ito 5

对我来说,scrollViewDidEndDragging效果更好scrollViewDidScroll:

第二种方法将在滚动过程中将每个位置发送给您,并引起问题,如果您要获取远程资源,则会多次击中端点,这是不好的。

基于@codafi解决方案的完整示例,并附@danielgomezrico关于如何计算contentHeight的评论

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
                  willDecelerate:(BOOL)decelerate {
    CGFloat actualPosition = scrollView.contentOffset.y;
    CGFloat contentHeight = scrollView.contentSize.height - (self.tableView.frame.size.height);
    if (actualPosition >= contentHeight) {
        // fetch resources
        [self.tableView reloadData];
    }
}
Run Code Online (Sandbox Code Playgroud)