Iphone 延迟加载的分页UIScrollview

Iphone 延迟加载的分页UIScrollview,iphone,ios,uiscrollview,Iphone,Ios,Uiscrollview,我需要有关uiscrollview实现的帮助,需要满足以下要求: 1) PaginEnabled=真。 2) 惰性页面加载。 3) 页面正在后台加载。因此,我需要首先运行加载页面X,然后得到页面已完全加载的通知,然后才允许用户滚动到该页面。 4) 能够更改当前页面 我的第一次尝试是覆盖ScrollViewDiEndDeAccelerating和scrollViewDidScroll,但我遇到了一半页面(当您停止一半页面上的滚动,然后等待新页面添加到滚动中)和空白页面(当用户滚动过快)的问题 我的

我需要有关uiscrollview实现的帮助,需要满足以下要求:

1) PaginEnabled=真。
2) 惰性页面加载。
3) 页面正在后台加载。因此,我需要首先运行加载页面X,然后得到页面已完全加载的通知,然后才允许用户滚动到该页面。
4) 能够更改当前页面

我的第一次尝试是覆盖ScrollViewDiEndDeAccelerating和scrollViewDidScroll,但我遇到了一半页面(当您停止一半页面上的滚动,然后等待新页面添加到滚动中)和空白页面(当用户滚动过快)的问题

我的第二次尝试是重写UIScrollView的layoutSubviews方法,并在那里进行所有计算。但它似乎非常逼真

因此,我很想找到任何类似实现的例子

现在我有这样的代码:

我已经实现了ScrollViewWillBeginDraging和ScrollViewDiEndDe减速:

在loadScrollViewWithPage中,我创建了页面视图控制器,该控制器在后台从服务器加载数据。我不会将视图添加到scrollview,直到它从服务器加载数据

- (void)loadScrollViewWithPage:(int)page forceAddToSuperview:(BOOL)value animated:(BOOL)animated
{
    DetailController *controller = page >= viewControllers.count ? [NSNull null] :[viewControllers objectAtIndex:page];

    if ((NSNull *)controller == [NSNull null])
    {
        controller = [[DetailController alloc] initWithNibName:@"DetailController" bundle:nil];        
        controller.delegate = self;
        controller.view.hidden = NO; //this will call viewDidLoad.

        if (page >= viewControllers.count) {
            [viewControllers addObject:controller];
        }
        else {
            [viewControllers replaceObjectAtIndex:page withObject:controller];
        }

        [controller release];
    }

    // add the controller's view to the scroll view
    if (controller.view && controller.view.superview == nil && (controller.isLoadedOrFailed || value)) {
        [self setNumberOfVisiblePages:visiblePagesCount+1];  

        if (page < selectedIndex) {
           // We are adding the page to the left of the current page,
     // so we need to adjust the content offset.
            CGFloat offset = (int)scrollView.contentOffset.x % (int)scrollView.frame.size.width;
            offset = scrollView.frame.size.width * (selectedIndex - minLoadedPageIndex) + offset;
            [scrollView setContentOffset:CGPointMake(offset, 0.0) animated:animated];       
        }

        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * (page - minLoadedPageIndex);
        frame.origin.y = 0;
        controller.view.frame = frame;        
        [scrollView addSubview:controller.view];
        [controller viewWillAppear:NO];
    }
}
-(void)加载ScrollViewWithPage:(int)page forceAddToSuperview:(BOOL)值已设置动画:(BOOL)已设置动画
{
DetailController*controller=page>=viewControllers.count?[NSNull]:[viewControllers objectAtIndex:page];
如果((NSNull*)控制器==[NSNull])
{
控制器=[[DetailController alloc]initWithNibName:@“DetailController”捆绑包:nil];
controller.delegate=self;
controller.view.hidden=NO;//这将调用viewDidLoad。
如果(第>=viewControllers.count页){
[查看控制器添加对象:控制器];
}
否则{
[viewControllers replaceObjectAtIndex:page with Object:controller];
}
[控制器释放];
}
//将控制器视图添加到滚动视图
if(controller.view&&controller.view.superview==nil&&(controller.isLoadedOrFailed | |值)){
[self-setNumberOfVisiblePages:visiblePagesCount+1];
如果(第页
此外,我还有一个DetailControllerdFinishDownload方法,当页面视图控制器的数据已加载时调用该方法

- (void)detailControllerDidFinishDownload:(DetailController *)controller
{

  ... //here I calculate new minLoadedPageIndex value

 // reset pages frames
 if (minLoadedPageIndex < oldMinPage) {
        for(int i=oldMinPage;i < [viewControllers count]; i++) {
            DetailController *detailsController = [viewControllers objectAtIndex:i];
            if ((NSNull *)detailsController != [NSNull null]) {
                CGRect frame = scrollView.frame;
                frame.origin.x = frame.size.width * (i - minLoadedPageIndex);
                frame.origin.y = 0;

                [detailsController.view setFrame:frame];
            }
        }
    }

   // load the page now or delay load until the scrolling will be finished
   if (!isScrolling) {
        [self loadScrollViewWithPage:[photoItems indexOfObject:controller.photoItem] forceAddToSuperview:NO animated:NO];
    }
    else {
        needDisplay = [photoItems indexOfObject:controller.photoItem];
        //NSLog(@"pageControlUsed is used!!! %d", [photoItems indexOfObject:controller.photoItem]);
    }
}
-(void)DetailControllerdFinishDownload:(DetailController*)控制器
{
…//这里我计算新的minLoadedPageIndex值
//重置页面框架
if(minLoadedPageIndex
我现在遇到的问题是,有时滚动条会在页面的中间(或接近中间的某个位置)发生碰撞,直到我稍微移动滚动条,滚动条才会跳转到最近的页面。我的测试表明,如果我滚动出内容视图框架(滚动视图已反弹)并等待加载新页面,就会出现这种情况。在10次滚动中的1次滚动中


谢谢,米哈伊尔

您同时需要很多东西。我建议你看看这个例子


这是一个很好的起点

你知道,不是我主宰比赛。谢谢这个例子太简单了。我比这个例子多做了500%。很难知道你做了什么,因为没有显示代码。去年,我发现五月对页面位置的计算是错误的,所以这是主要问题。我会放弃在加载页面时阻止用户滚动的要求;显示进度指示器似乎更方便用户,而且几乎不需要破坏UIScrollView的行为。我的客户想要它,我无法说服他放弃它:(
- (void)detailControllerDidFinishDownload:(DetailController *)controller
{

  ... //here I calculate new minLoadedPageIndex value

 // reset pages frames
 if (minLoadedPageIndex < oldMinPage) {
        for(int i=oldMinPage;i < [viewControllers count]; i++) {
            DetailController *detailsController = [viewControllers objectAtIndex:i];
            if ((NSNull *)detailsController != [NSNull null]) {
                CGRect frame = scrollView.frame;
                frame.origin.x = frame.size.width * (i - minLoadedPageIndex);
                frame.origin.y = 0;

                [detailsController.view setFrame:frame];
            }
        }
    }

   // load the page now or delay load until the scrolling will be finished
   if (!isScrolling) {
        [self loadScrollViewWithPage:[photoItems indexOfObject:controller.photoItem] forceAddToSuperview:NO animated:NO];
    }
    else {
        needDisplay = [photoItems indexOfObject:controller.photoItem];
        //NSLog(@"pageControlUsed is used!!! %d", [photoItems indexOfObject:controller.photoItem]);
    }
}