Skip to content

AA 1.23. Creating Scrollable Content with UIScrollView

rayastar edited this page Feb 15, 2015 · 1 revision

Problem

You have content that needs to get displayed on the screen, but it requires more real estate than what the device’s screen allows for.

Solution

Use the UIScrollView class.

First, let’s start with the implementation file of our view controller:

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) UIScrollView *myScrollView;
@property (nonatomic, strong) UIImageView *myImageView;
@end

And let’s place the image view inside the scroll view:

    UIImage *imageToLoad = [UIImage imageNamed:@"MacBookAir"];
    self.myImageView = [[UIImageView alloc] initWithImage:imageToLoad];
    self.myScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    [self.myScrollView addSubview:self.myImageView];
    self.myScrollView.contentSize = self.myImageView.bounds.size;
    self.myScrollView.delegate = self;
    [self.view addSubview:self.myScrollView];

One of the handy features of UIScrollView is support for delegation, so that it can report really important events to the app through a delegate. A delegate for a scroll view must conform to the UIScrollViewDelegate protocol. Here are some of the methods defined in this protocol:

scrollViewDidScroll: Gets called whenever the contents of a scroll view get scrolled.

scrollViewWillBeginDecelerating: Gets called when the user scrolls the contents of a scroll view and lifts his finger off the screen as the scroll view scrolls.

scrollViewDidEndDecelerating: Gets called when the scroll view has finished scrolling its contents.

scrollViewDidEndDragging:willDecelerate: Gets called when the user finishes dragging the contents of the scroll view. This method is very similar to the scrollViewDidEndDecelerating: method, but you need to bear in mind that the user can drag the contents of a scroll view without scrolling the contents. She can simply put her finger on the content, move her finger to any location on the screen and lift her finger, without giving the contents any momentum to move. This is dragging as opposed to scrolling. Scrolling is similar to dragging, but the user will give momentum to the contents’ movement by lifting her finger off the screen while the content is being dragged around, and not waiting for the content to stop before lifting her finger off the screen. Dragging is compa‐ rable to holding down the accelerator in a car or pedaling on a bicycle, whereas scrolling is comparable to coasting in a car or on a bicycle.

So let’s add some fun to our previous app. Now the goal is to set the alpha level of the image inside our image view to 0.50f (half transparent) when the user starts to scroll the scroll view and set this alpha back to 1.0f (opaque) when the user finishes scrolling. Let’s begin by conforming to the UIScrollViewDelegate protocol:

@interface ViewController () <UIScrollViewDelegate>

Then let’s implement this functionality:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    /* Gets called when user scrolls or drags */
    self.myScrollView.alpha = 0.50f;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    /* Gets called only after scrolling */
    self.myScrollView.alpha = 1.0f;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    /* Make sure the alpha is reset even if the user is dragging */
    self.myScrollView.alpha = 1.0f;
}

For this example code, I’ve prepared three images: an iPhone, an iPad, and a MacBook Air. I’ve placed them in their individual image views and added them to a scroll view. Then we can enable pagination by setting the value of the pagingEnabled property of the scroll view to YES:

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIImage *iPhone = [UIImage imageNamed:@"iPhone"];
    UIImage *iPad = [UIImage imageNamed:@"iPad"];
    UIImage *macBookAir = [UIImage imageNamed:@"MacBookAir"];
    CGRect scrollViewRect = self.view.bounds;
    self.myScrollView = [[UIScrollView alloc] initWithFrame:scrollViewRect];
    self.myScrollView.pagingEnabled = YES;
    self.myScrollView.contentSize = CGSizeMake(scrollViewRect.size.width * 3.0f,
                                               scrollViewRect.size.height);
    [self.view addSubview:self.myScrollView];
    CGRect imageViewRect = self.view.bounds;
    UIImageView *iPhoneImageView = [self newImageViewWithImage:iPhone
                                                         frame:imageViewRect];
    [self.myScrollView addSubview:iPhoneImageView];
    /* Go to next page by moving the x position of the next image view */
    imageViewRect.origin.x += imageViewRect.size.width;
    UIImageView *iPadImageView = [self newImageViewWithImage:iPad
                                                       frame:imageViewRect];
    [self.myScrollView addSubview:iPadImageView];
    /* Go to next page by moving the x position of the next image view */
    imageViewRect.origin.x += imageViewRect.size.width;
    UIImageView *macBookAirImageView =
    [self newImageViewWithImage:macBookAir
                          frame:imageViewRect];
    [self.myScrollView addSubview:macBookAirImageView];
}

- (UIImageView *) newImageViewWithImage:(UIImage *)paramImage frame:(CGRect)paramFrame
{
    UIImageView *result = [[UIImageView alloc] initWithFrame:paramFrame];
    result.contentMode = UIViewContentModeScaleAspectFit;
    result.image = paramImage;
    return result;
}
Clone this wiki locally