2

I'm struggling to understand a few questions that you might find simple about UIScrollView.

  1. Why do we increase the contentSize and not the bounds of the UIScrollView? Actually, I don't understand what the bounds and contentSize do.

  2. When I set pagingEnabled to YES, how does the scrollView know where to stop scrolling?

  3. I want to add a gap between pages in my UIScrollView. (pagingEnabled = YES) I searched on the Internet and I found the following code, that rob mayoff wrote:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];

    #define kGutterWidth 20

    UIScrollView *scrollView = self.scrollView;
    CGRect scrollViewFrame = scrollView.frame;
    scrollViewFrame.size.width += kGutterWidth;
    scrollView.frame = scrollViewFrame;

    CGSize scrollViewSize = scrollView.bounds.size;

    for (int i = 0; i < colors.count; i++) {
        CGRect frame = CGRectMake(scrollViewSize.width * i, 0,
            scrollViewSize.width - kGutterWidth, scrollViewSize.height);
        UIView *subview = [[UIView alloc] initWithFrame:frame];
        subview.backgroundColor = [colors objectAtIndex:i];
        [scrollView addSubview:subview];
        [subview release];
    }

    scrollView.contentSize = CGSizeMake(
        colors.count * scrollViewSize.width,
        scrollViewSize.height);
}

The source of the code: How to create a paging scrollView with space between views

This code works properly, but it doesn't matter as long as I don't understand it.

  1. I know that eventually the pages will be loaded with their original size, but I don't understand how does it happen, because each page is subtracted with kGutterWidth.

  2. Why did rob increase the scrollView's frame with kGutterWidth?

  3. OK, this questions might be sounded as stupid, but I really don't understand it. In the code, Rob created a new scrollView object that was called scrollView. It's value is equal to self.scrollView value. Well, I don't understand how changes that are done to scrollView, impact self.scrollView, because they are different objects. Their memory addresses are different.

I'm struggling to understand these questions for a long time. Today I've decided to write them here.

Thank you.

Community
  • 1
  • 1
Noam Solovechick
  • 1,127
  • 2
  • 15
  • 29

2 Answers2

5

1- You can check the actual description for the bounds properties of a UView:

The bounds rectangle, which describes the view’s location and size in its own coordinate system.

And the actual contentSize:

The size of the content view.

The first being related to the actual size of the UIView in relation to itself (being the frame in relation to its superView). The second is related to its contentSize, where a contentSize bigger than its frame, gives you the scrolling ability.

2- From the documentation:

If the value of this property is YES, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is NO.

I guess it is calculated, based on the size (width) of your UIScrollView versus its contentSize. For example a 640p contentSize UIScrollView with a 320p frame would have 2 "pages". (640/320 = 2).

3- The gap is created by putting the UIView that you have "inside" each page smaller than the actual page. Which is basically what Rob does here:

  CGRect frame = CGRectMake(scrollViewSize.width * i, 0,
            scrollViewSize.width - kGutterWidth, scrollViewSize.height);

So a UIScroll with the following frame (0.0f,0.0f,320.0f,480.0f) and with a contentSize of (1280.0f,480.0f) would give this:

1st item's frame => (0.0f,0.0f,300.0f,480.0f)

2nd item's frame => (320.0f,0.0f,300.0f,480.f)

3rd item's frame => (640.0f,0.0f,300.0f,480.0f)

4th item's frame=> (960.0f,0.0f,300.0f,480.0f)


Edit 1.0:

I don't understand it at all. what do you mean by "putting the view inside each page smaller than the actual page" ?

So let's take the example, I used: So you currently have 4 "pages", in fact what you have is basically the UIScrollView divided 3 times, which gives you 4 distinct places, that we can call pages. Inside each "page", in order to give a sense of "space" between each page, you are going to put a UIView smaller than the actual page.

Edit 2.0:

Maybe something more visual will help you out:

enter image description here

Edit 3.0:

It's easy if you understand how paging works... 320px + 20px = 340px which is more than the 320px of the iPhone screen size. Since each UIView added to the UIScrollView has 340-20 = 320px, you will have "Pages" with the size of 340px. So 340*3 (number of UIViews) it gives 1020px wich in the end is basically 3 UIViews + 3 Spaces

Rui Peres
  • 25,741
  • 9
  • 87
  • 137
  • 1. If the bounds has its own coordinate system and in relation to the scrollView, why the bounds' width isn't equal to the contentSize's width? – Noam Solovechick Mar 19 '13 at 13:28
  • 2. the calculate is based on the frame's width or the bounds' width? (or are they equal?) – Noam Solovechick Mar 19 '13 at 13:31
  • The `contentSize` is related to what is inside it while the `width` is related to what you can see... Put a pair of binoculars... What you see is the `view`, the world is the `contentSize`. The capacity of turning around the binoculars is the scrolling... Does it makes sense my example? – Rui Peres Mar 19 '13 at 13:31
  • If I am not mistaken with would be according to it's bounds. See this to better understand the different: http://littlehales.files.wordpress.com/2012/03/coords.jpg – Rui Peres Mar 19 '13 at 13:34
  • So when we're talking about UIScrollView, the bounds.width is always equal to frame.width , and the only difference between them is the coordination system? – Noam Solovechick Mar 19 '13 at 13:50
  • Rotations that might happen on the `UIView` (in this case a `UIScrollView`), will make the width/height of the bounds be different from the frame's width/height. – Rui Peres Mar 19 '13 at 13:51
  • And about your answer to my third question (gap between pages) - I don't understand it at all. what do you mean by "putting the view inside each page smaller than the actual page" ? I still don't understand how the gap is created :( – Noam Solovechick Mar 19 '13 at 13:52
  • If it helps understand better, you can use a regular `UIView`, which has bounds (i.e. an origin and a size), and put inside a bigger view, which is then going to be cropped. The size of the bigger view is the `contentSize`. Now, if you move the origin of the bounds of the outter `UIView`, you're going to translate the inner view, and see a different part of it. An `UIScrollView` works the same, it just adds touch management, scrollers, and a lot of convenience methods to zoom, scroll with animation, use pages, etc. See *View Geometry and Coordinate Systems* in Apple documentation. – Guillaume Mar 19 '13 at 14:30
  • Ok, now I'm completely frustrated. In your photo you can see the space of the first page right away, while in reality you can see the space only when you scroll. Also each page in your photo is smaller than the scrollView's frame, while in reality each page fills the whole scrollView's frame. I still don't understand why should I increase the scrollView.frame.width and subtract each page frame.width. I'm extremely grateful you're trying to teach me that, but I still don't get it :( @Guillaume I do understand what you're saying, but my problem is the space between views :( – Noam Solovechick Mar 19 '13 at 14:34
  • I did a mistake on the image, check again, please. If you still don't get it, you contact me by using my email. – Rui Peres Mar 19 '13 at 14:35
  • @NoamSolovechick I tested the code, and the final image is the one that I am presenting. – Rui Peres Mar 19 '13 at 14:54
  • @JackyBoy Where can I find your email? – Noam Solovechick Mar 19 '13 at 15:49
  • sauron[dot]is[dot]alive@gmail[dot]com – Rui Peres Mar 19 '13 at 16:30
0
  1. The bounds is the real container of the view. the contentSize is the "viewable" size. Example: a table of 100 px of height but contains a dozen of cell, with 20 px for cell. Your total size is ≈ 240 px, this is the contentSize, but the bounds height are 100 px.
Vincent Saluzzo
  • 1,377
  • 1
  • 11
  • 13