Paging-enabled UIScrollView


UIPageControl与启用Page的UIScrollView经常结合使用用于浏览图片。

本文介绍一些使用UIPageControlUIScrollView的开源代码。

一.苹果公司的示例代码PageControl

  • 在PhoneContentController视图控制器中包含UIScrollView,UIPageControl,在UIScrollView中放置的是一组内容视图控制器MyViewController的view;
  • 当UIScrollView的滑动事件scrollViewDidScroll中,判断当前需要显示的页,设置UIPageControll的currentPage属性为当前页索引,将当前页和前一页,后一页的需要显示的内容加载到UIScrollView。
        CGFloat pageWidth = scrollView.frame.size.width;
        int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
        pageControl.currentPage = page;
        [self loadScrollViewWithPage:page - 1];
        [self loadScrollViewWithPage:page];
        [self loadScrollViewWithPage:page + 1];
  • 加载过程即创建(若尚未创建)对应的内容视图控制器,并将内容视图控制器的view加入的UIScrollView中(若尚未加入)。
    - (void)loadScrollViewWithPage:(int)page
    {
        if (page < 0)
            return;
        if (page >= kNumberOfPages)
            return;
    
        // replace the placeholder if necessary
        MyViewController *controller = [viewControllers objectAtIndex:page];
        if ((NSNull *)controller == [NSNull null])
        {
            controller = [[MyViewController alloc] initWithPageNumber:page];
            [viewControllers replaceObjectAtIndex:page withObject:controller];
            [controller release];
        }
    
        // add the controller's view to the scroll view
        if (controller.view.superview == nil)
        {
            CGRect frame = scrollView.frame;
            frame.origin.x = frame.size.width * page;
            frame.origin.y = 0;
            controller.view.frame = frame;
            [scrollView addSubview:controller.view];
    
            NSDictionary *numberItem = [self.contentList objectAtIndex:page];
            controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]];
            controller.numberTitle.text = [numberItem valueForKey:NameKey];
        }
    }
  • 在创建UIPageControl时要设置UIPageControll的事件处理,当PageControl的页索引更新时,同时更新UIScrollView中的显示。
    [pageControl addTarget:self action:@selector(changePage:) forControlEvents:UIControlEventValueChanged];
    
    - (IBAction)changePage:(id)sender
    {
        int page = pageControl.currentPage;
    
        // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
        [self loadScrollViewWithPage:page - 1];
        [self loadScrollViewWithPage:page];
        [self loadScrollViewWithPage:page + 1];
    
    	// update the scroll view to the appropriate page
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        [scrollView scrollRectToVisible:frame animated:YES];
    }

核心代码:
PhoneContentController.h
PhoneContentController.m

工程代码:PageControl.zip

二.AdrianAFImageViewer

AFImageViewer是由UIScrollView和UIPageControl组成的视图框架,用于图片浏览,其对苹果的PageControl例子进行了扩展,支持三种获取需显示图片的方式。

  • 异步:传递image urls数组给AFImageViewer,AFImageViewer会异步下载这些图片并显示。
        self.imageViewer.imagesUrls = [self imageUrls];
        self.imageViewer.contentMode = UIViewContentModeScaleAspectFill;
        self.imageViewer.loadingImage = [UIImage imageNamed:@"dark_blue.jpg"];
        self.imageViewer.tempDownloadedImageSavingEnabled = YES;
  • 数据源:直接传递UIImage对象数组给AFImageViewer,AFImageViewer自动显示这些图片。
        self.imageViewer.images = [self images];
        self.imageViewer.contentMode = UIViewContentModeScaleAspectFit;
  • Delegate:通过delegate获取需显示的图片及数量。
    [self.imageViewer setContentMode:UIViewContentModeScaleAspectFill];
    self.imageViewer.delegate = self;
    
    -(int)numberOfImages
    {
        return num;
    }
    -(UIImageView *)imageViewForPage:(int)page
    {
        ...
        return imgView;
    }

核心代码:
AFImageViewer.h
AFImageViewer.m

工程代码:https://github.com/AdrianFlorian/AFImageViewer

三.blog.proculo.dePaging-enabled UIScrollView With Previews

在App Store中浏览程序图片时,在当前图片两侧可看到之前和之后图片的一部分,让用户得知之前或之后还有内容。
实现这种效果的方法是将UIScrollView的frame宽度缩小,使之小于screen的宽度,并将clipsToBounds设为NO,这样在UIScrollView当前Frame两侧的内容也可显示出来。
这样存在一个问题,UIScrollView当前Frame两侧的内容不响应拖动事件,解决方法时,将UIScrollView嵌入于一个UIView中,而此UIView的宽度为Screen的宽度,然后重写UIView的hitTest方法,当点击的点在UIView内时,hitTest返回UIScrollView。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
	if ([self pointInside:point withEvent:event]) {
		return _scrollView;
	}
	return nil;
}

代码:https://github.com/alexrepty/Paging-Enabled-UIScrollView-With-Previews

四.Björn SållarpBSPreviewScrollView

BSPreviewScrollView对Paging-enabled UIScrollView With Previews中代码进行封装和扩展,将UIScrollView封装在其中,统一处理UIScrollView的各种事件。Paging-enabled UIScrollView With Previews中的hitTest方法总是返回UIScrollView对象,从而使UIScrollView内部视图的点击/触摸事件无法响应。这里修改如下:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

	// If the point is not inside the scrollview, ie, in the preview areas we need to return
	// the scrollview here for interaction to work
	if (!CGRectContainsPoint(scrollView.frame, point)) {
		return self.scrollView;
	}

	// If the point is inside the scrollview there's no reason to mess with the event.
	// This allows interaction to be handled by the active subview just like any scrollview
	return [super hitTest:point	withEvent:event];
}


在hitTest方法,仅在点击位置在UIScrollView之外时才返回UIScrollView对象,这样点击在UIScrollView内部时,就可以将点击/触摸事件传递给UIScrollView的子视图。
类似App Strore中图片两边的空白间隙需要用户自己处理,即要显示的图片要比UIScrollView的frame宽度略小些。

核心代码:
BSPreviewScrollView.h
BSPreviewScrollView.m

工程代码:ScrollViewPreview.zip

五.Matt GallagherMultiple virtual pages in a UIScrollView with just 2 child views

苹果公司的PageControl示例代码为每个要显示的页都创建一个视图控制器,Matt Gallagher讲述了一个方法用两个实际的视图控制器模拟多个页显示的方法。其核心思想是,保存两个内容视图控制器:currentPage和nextPage,currentPage为当前显示的页,当向右滑动时,更新nextPage的内容为下一页内容,并放在UIScrollView的对应位置上;当向左滑动时,更新nextPage的内容为前一页内容,并放置在UIScrollView前一页的位置上。此方法应用的场景应该时,重新load数据时速度比较快,不然显示就会很缓慢,影响平滑滑动的效果。
代码中奇怪的是,在启动时会自动滑至第2页,在滑动过程中并没有完整按页显示,在内容中还会显示之前页的部分内容,滑动还有反弹效果,还没看明白是哪里的问题。

核心代码:
PagingScrollViewController.h
PagingScrollViewController.m

代码:PagingScrollView.zip

参考:
UIPageControl Class Reference
UIScrollView Class Reference
PageControl 苹果示例代码
AFImageViewer
Paging-enabled UIScrollView With Previews
iPhone/iPad – AppStore like UIScrollView with paging and preview
Multiple virtual pages in a UIScrollView with just 2 child views

原文地址:http://www.winddisk.com/2012/06/11/paging-enabled-uiscrollview/

优质内容筛选与推荐>>
1、NuGet学习笔记(2)——使用图形化界面打包自己的类库
2、程序员脱发?看看各个创始人的发量?
3、tcp的半连接与完全连接队列(三)源码分析
4、北航面向对象Round Two
5、mysql多个TimeStamp设置(转)


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号