Tuesday 12 April 2011

UIScrollView


UIScrollView – A really simple tutorial


The UIScrollView it’s a very versatile class, you can handle zooming, panning, scrolling, etc, and I have no intention of explaining all the properties and delegates (well, if you want to know something about the UIScrollView, fell free to request it in the comments, just let me know =D ), the documentation itself is pretty good, so you should give it a look.

Basic:

       There’s 2 very important properties in UIScrollView, the contentSize and the contentOffset.
The contentsize is the width and height of your content, it’s a CGSize and a property of UIScrollView, let’s say that you have an image that’s 500×500, it would not fit on the iPhone screen, right? So, set your contentsize to 500,500. If you want to add more scrollable space at the bottom or at the top, you can use the property contentInset.top and contentInset.bottom, so you can add some extra space without changing the contentsize. And why would you need these insets? Well, if you have a UINavigationBar or a UIToolBar, like the photos app, you will use this.

Every UIScrollView has a scroll indicator (it’s visible by default, but if you want, you can hide it with showsHorizontalScrollIndicator and showsVerticalScrollIndicator), to give an indication of how far in the content you are, and you can change where the indicator starts using the scrollIndicatorInsets.top just like the contentInsets.The contentOffset is the point that is currently visible, this point represents the top left of your screen. The contentOffset discards the contentInsets, so it can happen that the contentInset is negative, that’s not a problem.

The only thing that you need to have a functional UIScrollView is the UIView that you want to display and the contentSize of this UIView, so let’s start coding…

Create a View-based Application and name it SimpleScroll. Again, I always use the Window-based Application for my projects, but let’s pick the View-based just to speed things up.
Go to your SimpleScrollViewController class, in the loadView method and create your UIScrollView, we will create it with the same width and heigh as the view from SimpleScrollViewController

UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
Enable the pagination
scroll.pagingEnabled = YES;
If the value of this property is YES, the scroll view stops on multiples of the view bounds when the user scrolls. The default value is NO.

Create all three UIViews

NSInteger numberOfViews = 3;
for (int i = 0; i < numberOfViews; i++) {
CGFloat yOrigin = i * self.view.frame.size.width;
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];
[scroll addSubview:awesomeView];
[awesomeView release];
}


Set the UIScrollView contentSize

scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);

The contentSize is just the sum of the widths of the three UIViews, if the width of each UIView is 320, and we have three UIViews, your contentSize width will be 920.



Add the UIScrollView to the SimpleScrollViewController UIView

[self.view addSubview:scroll];
[scroll release];
And you’re done :)



At the end, you should have something like this :


- (void)loadView {
[super loadView];
self.view.backgroundColor = [UIColor redColor];
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

scroll.pagingEnabled = YES;

NSInteger numberOfViews = 3;
for (int i = 0; i < numberOfViews; i++) {
CGFloat yOrigin = i * self.view.frame.size.width;

UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];

awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];

[scroll addSubview:awesomeView];

[awesomeView release];

}
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);

[self.view addSubview:scroll];
[scroll release];

}

As you can see, I changed the background color of the SimpleScrollViewController UIView to red, just to make sure that you can distinguish the content of the UIScrollView.

 



UIScrollView and Zoom

Create a ScrollView as:

- (void)loadView {
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
scroll.backgroundColor = [UIColor blackColor];
scroll.delegate = self;
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.JPG"]];
scroll.contentSize = image.frame.size;
[scroll addSubview:image];
scroll.minimumZoomScale = scroll.frame.size.width / image.frame.size.width;
scroll.maximumZoomScale = 2.0;
[scroll setZoomScale:scroll.minimumZoomScale];
self.view = scroll;
[scroll release];
}
we have to implement a UIScrollView delegate method called
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return image;
}

Place the image is on the center of your screen


- (CGRect)centeredFrameForScrollView:(UIScrollView *)scroll andUIView:(UIView *)rView {

CGSize boundsSize = scroll.bounds.size;
CGRect frameToCenter = rView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
{
frameToCenter.origin.x = (boundsSize.width – frameToCenter.size.width) / 2; } else { frameToCenter.origin.x = 0;
} // center vertically
if (frameToCenter.size.height < boundsSize.height)
{
frameToCenter.origin.y = (boundsSize.height – frameToCenter.size.height) / 2; }
else {
frameToCenter.origin.y = 0;
}
return frameToCenter;
}

This method will receive your UIScrollView and the UIView that you are zooming and calculate the correct frame for your UIView and return a CGRect. All you have to do is call this method on your scrollViewDidZoom delegate, that’s get called everytime that there’s some zooming, and you are ready.

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
image.frame = [self centeredFrameForScrollView:scrollView andUIView:image];;
}


1 comment: