164

Can someone explain to me what the contentInset property in a UIScrollView instance is used for? And maybe provide an example?

Sandy
  • 4,714
  • 4
  • 42
  • 69
ForeignerBR
  • 2,339
  • 4
  • 22
  • 27

5 Answers5

246

It sets the distance of the inset between the content view and the enclosing scroll view.

Obj-C

aScrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 7.0);

Swift 5.0

aScrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 7.0)

Here's a good iOS Reference Library article on scroll views that has an informative screenshot (fig 1-3) - I'll replicate it via text here:

  _|←_cW_→_|_↓_
   |       | 
---------------
   |content| ↑
 ↑ |content| contentInset.top
cH |content|
 ↓ |content| contentInset.bottom
   |content| ↓
---------------
  _|_______|___ 
             ↑


   (cH = contentSize.height; cW = contentSize.width)

The scroll view encloses the content view plus whatever padding is provided by the specified content insets.

Nikita
  • 389
  • 3
  • 9
jball
  • 23,602
  • 8
  • 65
  • 91
  • is it used to add a padding to the UIScrollView then? If not could you give me a practical example. My problem is not how to implement it but when to implement it. – ForeignerBR Dec 31 '09 at 01:29
  • 29
    Yes, it pads the content on the inside of the scroll view. It's akin to the CSS `padding` property. – Marc W Dec 31 '09 at 01:37
  • Sorry to piggyback on this, I can move it its own question, but based on this, what actually happens if you set each contentInset value to 0 other than the contentHeight for example? Does that force the whole scrollview to be the height you set it to? – jakev Apr 14 '13 at 17:33
  • @jakev No, the .frame property controls the scrollview's dimensions within it's parent (See this answer: http://stackoverflow.com/questions/5361369/uiview-frame-bounds-and-center#answer-11282765). Setting the contentInsets to 0 for all sides simply means that the content will not be padded at all within the scrollview. So when you scroll to the top, the content is sitting right against the top of the scrollview. If you scroll to the bottom, the content reaches right to the bottom of the scrollview. – Jeremy Wiebe Aug 13 '13 at 15:34
  • is it possible to keep contentInset always even when scrolling always keep marin to top (contenInset) of scrollView – Chlebta Dec 28 '15 at 11:17
87

While jball's answer is an excellent description of content insets, it doesn't answer the question of when to use it. I'll borrow from his diagrams:

  _|←_cW_→_|_↓_
   |       | 
---------------
   |content| ↑
 ↑ |content| contentInset.top
cH |content|
 ↓ |content| contentInset.bottom
   |content| ↓
---------------
   |content|    
-------------↑-

That's what you get when you do it, but the usefulness of it only shows when you scroll:

  _|←_cW_→_|_↓_
   |content| ← content is still visible
---------------
   |content| ↑
 ↑ |content| contentInset.top
cH |content|
 ↓ |content| contentInset.bottom
   |content| ↓
---------------
  _|_______|___ 
             ↑

That top row of content will still be visible because it's still inside the frame of the scroll view. One way to think of the top offset is "how much to shift the content down the scroll view when we're scrolled all the way to the top"

To see a place where this is actually used, look at the build-in Photos app on the iphone. The Navigation bar and status bar are transparent, and the contents of the scroll view are visible underneath. That's because the scroll view's frame extends out that far. But if it wasn't for the content inset, you would never be able to have the top of the content clear that transparent navigation bar when you go all the way to the top.

Fabian
  • 6,887
  • 2
  • 24
  • 25
8

Content insets solve the problem of having content that goes underneath other parts of the User Interface and yet still remains reachable using scroll bars. In other words, the purpose of the Content Inset is to make the interaction area smaller than its actual area.

Consider the case where we have three logical areas of the screen:

TOP BUTTONS

TEXT

BOTTOM TAB BAR

and we want the TEXT to never appear transparently underneath the TOP BUTTONS, but we want the Text to appear underneath the BOTTOM TAB BAR and yet still allow scrolling so we could update the text sitting transparently under the BOTTOM TAB BAR.

Then we would set the top origin to be below the TOP BUTTONS, and the height to include the bottom of BOTTOM TAB BAR. To gain access to the Text sitting underneath the BOTTOM TAB BAR content we would set the bottom inset to be the height of the BOTTOM TAB BAR.

Without the inset, the scroller would not let you scroll up the content enough to type into it. With the inset, it is as if the content had extra "BLANK CONTENT" the size of the content inset. Blank text has been "inset" into the real "content" -- that's how I remember the concept.

Faisal Memon
  • 1,379
  • 11
  • 22
4

It's used to add padding in UIScrollView

Without contentInset, a table view is like this:

enter image description here

Then set contentInset:

tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)

The effect is as below:

enter image description here

Seems to be better, right?

And I write a blog to study the contentInset, criticism is welcome.

shim
  • 7,170
  • 10
  • 62
  • 95
fujianjin6471
  • 4,860
  • 1
  • 32
  • 31
2

Great question.

Consider the following example (scroller is a UIScrollView):

float offset = 1000;
[super viewDidLoad];
for (int i=0;i<500; i++) {
    UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(i * 100, 50, 95, 100)] autorelease];
    [label setText:[NSString stringWithFormat:@"label %d",i]];
    [self.scroller addSubview:label];
    [self.scroller setContentSize:CGSizeMake(self.view.frame.size.width * 2 + offset, 0)];
    [self.scroller setContentInset:UIEdgeInsetsMake(0, -offset, 0, 0)];
}

The insets are the ONLY way to force your scroller to have a "window" on the content where you want it. I'm still messing with this sample code, but the idea is there: use the insets to get a "window" on your UIScrollView.

Dan Rosenstark
  • 64,546
  • 54
  • 267
  • 405