UIScrollView和UIPageControl结合实现图片浏览

iOS中具有图片类的app通常都会有滑动浏览的功能,许多app第一次启动时,也会用UIScrollView+UIPageControl来展示新功能。今天探索一下如何实现该功能。

首先介绍下UIScrollView, UIScrollView中有个重要的属性是contentSize,用于界定滑动范围的大小。UIScrollView本身frame是我们在屏幕上可视部分,也就是说contentSize的宽要大于UIScrollView.frame.size.width才能实现滑动浏览的功能。

另外,图片浏览,为了避免一开始就load所有的UIImageView,可以选择仅仅load当前浏览页面及前后三个UIImageView。而这之外的page上的子视图我们都设置为[NSNull null]。我们在检测到滑动后,再lazy load 所需的UIImageView。

#import "ViewController.h"

 

@interface ViewController () <UIScrollViewDelegate>

 

@property (nonatomic, strong) UIScrollView *scrollView;

@property (nonatomic, strong) UIPageControl *pageControl;

 

@property (nonatomic, strong) NSArray *pageImages;

@property (nonatomic, strong) NSMutableArray *pageViews;

 

- (void)loadVisiblePages;

- (void)loadPage:(NSInteger)page;

- (void)purgePage:(NSInteger)page;

 

@end

 

@implementation ViewController

 

@synthesize scrollView;

@synthesize pageControl;

@synthesize pageImages;

@synthesize pageViews;

 

- (void)viewDidLoad {

    [super viewDidLoad];

    

    // 1

    pageImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"2.jpg"],

                  [UIImage imageNamed:@"5.jpg"],[UIImage imageNamed:@"2.jpg"], [UIImage imageNamed:@"5.jpg"],nil];

    NSInteger pageCount = pageImages.count;

    pageViews = [[NSMutableArray alloc]init];

    for (NSInteger i=0; i<pageCount; i++) {

        [self.pageViews addObject:[NSNull null]];

    }

    

    // 2

    self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 568)];

    [self.view addSubview:scrollView];

    scrollView.delegate = self;

    self.pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 400, 320, 20)];

    self.pageControl.currentPage = 0;

    [self.pageControl setNumberOfPages:pageCount];

    [pageControl setBackgroundColor:[UIColor grayColor]];

    [self.view addSubview:pageControl];

    

}

 

- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];

    CGSize pagesScrollViewSize = self.scrollView.frame.size;

    self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);

    [self loadVisiblePages];

}

 

- (void)loadVisiblePages {

    CGFloat pageWidth = scrollView.frame.size.width;

    NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x*2.0f+pageWidth)/(pageWidth*2.0f));

    

    pageControl.currentPage = page;

    

    NSInteger firstPage = page - 1;

    NSInteger lastPage = page + 1;

    

    // Pure anything before the first page

    for (NSInteger i = 0; i< firstPage; i++) {

        [self purgePage:i];

    }

    

    // Load pages in our range

    for (NSInteger i = firstPage; i<=lastPage; i++) {

        [self loadPage:i];

    }

    

    // Purge anything after last page

    for (NSInteger i = lastPage+1; i<self.pageImages.count; i++) {

        [self purgePage:i];

    }

    

    

}

 

- (void)loadPage:(NSInteger)page {

    if (page<0 ||  page>=self.pageImages.count) {

        return;

    }

    

    UIView *pageView = [self.pageViews objectAtIndex:page];

    if ((NSNull *)pageView == [NSNull null]) {

        CGRect frame = self.scrollView.bounds;

        frame.origin.x = frame.size.width * page;

        frame.origin.y = 0.0f;

        

        UIImageView *imageView = [[UIImageView alloc]initWithImage:[self.pageImages objectAtIndex:page]];

        imageView.contentMode = UIViewContentModeScaleAspectFit;

        imageView.frame = frame;

        [self.scrollView addSubview:imageView];

        [self.pageViews replaceObjectAtIndex:page withObject:imageView];

        

    }

    

}

 

- (void)purgePage:(NSInteger)page {

    

    if (page < 0 || page >= self.pageImages.count) {

        // If it's outside the range of what you have to display, then do nothing

        return;

    }

    

    // Remove a page from the scroll view and reset the container array

    UIView *pageView = [self.pageViews objectAtIndex:page];

    if ((NSNull*)pageView != [NSNull null]) {

        [pageView removeFromSuperview];

        [self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];

    }

    

}

 

#pragma mark - Scroll View delegate

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

    [self loadVisiblePages];

}

 

几个注解:

-判断当前页面是第几个页面时,我们通过UIScrollView.contentOffset.x和pageWidth来判断,这里有一点数学上的运算。

-为了监测scrollView滑动的变化,设置scrollView的delegate,并且实现delegate中scrollViewDidScroll:方法。

 

posted @ 2015-02-14 23:36  jokerlu  阅读(285)  评论(0编辑  收藏  举报