26

I would like to display an image (width: 320 pixels, height: 1250 pixels) in an image view.

When I compile the application I get no scrolling at all. The view stays fixed.

What I did:

  1. Added an UIScrollView via Interface Builder to my view.
  2. Added an UIImageView via Interface Builder to my view.
  3. Verified that UIImageView is below UIScrollView in Interface Builder.
  4. Set the size of the UIScrollView with ViewDidLoad.

How do I do this?

Code:

- (void)viewDidLoad
{
    [super viewDidLoad];
    scrollView.contentSize = CGSizeMake(320, 1250);
}

Screenshots:

ImageView:

Enter image description here

ScrollView:

Enter image description here Enter image description here

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    why does your scrollview have a size of 320 x 1294? If your scrollview has the same size as its content it doesn't scroll. – Matthias Bauch Mar 14 '12 at 13:26
  • My fault, should actually be 320x1250. So the scroll view has to be slightly larger than the image I want to display? Will try it. –  Mar 14 '12 at 13:30
  • Doesn't work, now the image has 300x1000 (Scroll view still has 320x1250) but I get no scrolling. –  Mar 14 '12 at 13:36
  • nope. the scrollview has to be smaller. It must be completely visible on screen. If you want a fullscreen scrollview that will come down to a size of 320x460 – Matthias Bauch Mar 14 '12 at 13:53
  • Info: I have just created a new project in Xcode and did what I did before, scrolling works BUT gets disabled when I add a toolbar. Do I have to react with the toolbar addition somehow in the code? –  Mar 14 '12 at 14:01
  • This YouTube video perfectly explains how to set an UIScrollView: [xCode 4 Tutorial (UIScrollView)](http://www.youtube.com/watch?v=PkheIhGPbH0). – Stéphane Bruckert Jul 02 '13 at 19:13

17 Answers17

28

I just have done the same task.. Try this one.....

scrollView.delegate = self;
scrollView.scrollEnabled = YES;

int scrollWidth = 120;
scrollView.contentSize = CGSizeMake(scrollWidth,80);     


int xOffset = 0;
imageView.image = [UIImage imageNamed:[imagesName objectAtIndex:0]];

for(int index=0; index < [imagesName count]; index++)
{       
    UIImageView *img = [[UIImageView alloc] init];
    img.bounds = CGRectMake(10, 10, 50, 50);
    img.frame = CGRectMake(5+xOffset, 0, 50, 50);
    NSLog(@"image: %@",[imagesName objectAtIndex:index]);
    img.image = [UIImage imageNamed:[imagesName objectAtIndex:index]];
    [images insertObject:img atIndex:index];         
    scrollView.contentSize = CGSizeMake(scrollWidth+xOffset,110); 
    [scrollView addSubview:[images objectAtIndex:index]];

    xOffset += 70;
}

Also set this one....

imagesName = [[NSArray alloc]initWithObjects:@"image1.jpg",@"image2.jpg",@"image3.jpg",@"image4.jpg",@"image5.jpg",@"image6.png",@"image7.png",@"image9.png",nil];
    images = [[NSMutableArray alloc]init];
Krunal
  • 1,318
  • 1
  • 13
  • 31
  • If you are not in an ARC environment this piece of code will leak since you are allocating memory for `UIImageView *img = [[UIImageView alloc] init];` but you are never releasing it. I'd rather recommend to release it before every iteration ends rather than autorelease it if you have a lot of images since you never know when the runtime will autorelease them. – Alex Salom Aug 27 '12 at 07:16
  • 2
    Alex: The advice to release manually at the end of the loop is good for non-ARC code. One thing though, we DO know exactly when the runtime will release the images if you use autorelease. It will always happen at the end of the the event loop. This is reference counting, not garbage collection. – MindJuice Aug 28 '12 at 01:05
  • 1
    This is the part that was missing for me: scrollView.contentSize = CGSizeMake(scrollWidth,80); conentSize MUST be bigger than the scrollView's frame size. – StinkyCat Aug 13 '13 at 10:33
  • Not sure why this is the accepted answer as the OP asked about showing a single image. Anyway the point is that the scrollView.contentSize needs to be bigger than the scrollViews frame. – wuf810 Aug 29 '14 at 18:52
26

So for me the problem was that setting the content size didn't work in viewDidLoad(). I tried everything and I didn't understand why it wouldn't want to work, and then I tried the same stuff in viewDidAppear() and it magically worked...

gitaarik
  • 42,736
  • 12
  • 98
  • 105
  • 1
    This also did the trick for me and is a really simple solution. Apple needs make this "just work", however, as adding a scroll view is a common action and should not require any fussing as it does not. Thanks! – John Contarino Jun 28 '14 at 00:02
  • 1
    I'm not sure how you are setting `scrollView`, but the most common cause of errors like this is that outlets that are set in Interface Builder (XIB or storyboard) are not set before `viewDidLoad`. You may be calling a setter on a `nil` object. – Scott H Jan 24 '15 at 19:12
10

From you last screenshot and from your comments it looks like your scrollView is way to big. The scrollview must be visible on screen completely. For example a full screen UIScrollView on iPhone would have a size of 320 x 460.

If the scrollview is the same size as its content you can't scroll.

The greenish rectangle shows the size of your scrollview, the pinkish the size of your content (your image):

enter image description here

Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • Thanks, didn't know that the ScrollView can't be larger than the iPhone screen. Now it's clear but I'm still wondering why it works on my other project I just created (but stops scrolling when I add a toolbar) –  Mar 14 '12 at 14:08
7

Xcode 11+, Swift 5

You can find the complete solution here.

Đorđe Nilović
  • 3,600
  • 1
  • 25
  • 20
6

I came across this same issue on iOS6 and the solution was to programmatically adjust the ContentSize. So I will just quote from Raja (above) to show this:

CGSize scrollViewContentSize = CGSizeMake(320, 400);
[self.scrollView setContentSize:scrollViewContentSize];

NOTE: I was not having this issue on iOS5.. seems like iOS6 decided to do alot of prank just like the rotation/orientation saga

  • the second value of the size needs to be larger than the one signed in the Storyboard if you use one. Otherwise no scrolling – brainray Jul 03 '13 at 16:57
6

Since Xcode 5 it does not work like before. Also scrolling to the end of a scrollable text field makes problems. There are also differences between doing it on iPhone or iPad. On iPhone it worked without delayed timer.

This worked for me:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSTimer *timerforScrollView;
    timerforScrollView =[NSTimer scheduledTimerWithTimeInterval:0.1
           target:self selector:@selector(forScrollView)userInfo:nil repeats:NO];   
}

- (void) forScrollView {
    [scrollviewPad setScrollEnabled:YES];
    [scrollviewPad setContentSize:CGSizeMake(768, 1015)]; // must be greater then the size in Storyboard
}
Walter Schurter
  • 997
  • 9
  • 14
  • @NoraAlnashwan I had a similar problem where setting the contentSize wasn't updating the scrollview at all. This answer put me on the right path which was to put it in a `DispatchQueue.main.async { }` – Christopher Dec 19 '16 at 08:36
6

I found I had a similar problem but none of the above code worked. The issue was due to autolayout. I found that if I turned off autolayout by going to the storyboard clicking on Utilities -> File Inspector and unchecked Use Autolayout the scrolling did work (I also set scroll.contentSize = ...).

Julius
  • 576
  • 5
  • 12
3

Don't forget to add the category protocol to the interface, like this

@interface MyViewController : <UIScrollViewDelegate>

If you don't, you will not be able to set the scroll view delegate to self

(i.e. [MyScrollView setDelegate:self];)

If you do this, it should work.

My code is:

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [contentScrollView setDelegate:self];
    [contentScrollView setScrollEnabled:YES];
    contentScrollView.contentSize = CGSizeMake(310, 500);
    contentScrollView.frame = CGRectMake(5, 188, 310, 193);
}
Pang
  • 9,564
  • 146
  • 81
  • 122
werdsackjon
  • 394
  • 4
  • 11
3

Sometimes autoLayout checkbox is ticked in the xib. That also creates this issue in xcode 5. Which makes the UIScrollView scrolling off.

Vinay Kumar
  • 3,257
  • 1
  • 20
  • 19
2

Did you assign the scroll's view delegate? Always remember these:

[self.scrollView setDelegate:self]; 
[self.scrollView setScrollEnabled:YES];
Alex Salom
  • 3,074
  • 4
  • 22
  • 33
  • Yes, I did it in InterfaceBuilder. (Just tried to do it programm. in ViewDidLoad and deleted the connection in IB first but problem persists.) –  Mar 14 '12 at 13:26
1

You could try disabling AutoLayout. In XCode 5 I tested all the above answers and I could only scroll it by disabling autolayout and activating all autosizing masks under the Size Inspector. The following code was used too:

self.scrollView.contentSize = CGSizeMake(320, 900);
self.scrollView.delegate = self;
self.scrollView.scrollEnabled = YES;
self.scrollView.frame = self.view.frame;
jturolla
  • 6,596
  • 7
  • 26
  • 41
1

The image view has to be a subview (so inside AND below) of the scrollview. From your description it seems they are paralell

Tomen
  • 4,854
  • 5
  • 28
  • 39
  • I think I did it correctly, can you have a look at the new screenshot? On top is the view, below the scroll view, below the image view. Am I wrong? –  Mar 14 '12 at 13:09
1

You forgot one line. Add this to your view load function:

[scrollView setScrollEnabled:YES];
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Allison
  • 2,213
  • 4
  • 32
  • 56
  • Unfortunately that doesn't fix it. Added the line but scrolling is still not possible, –  Mar 14 '12 at 13:07
  • Maybe you should as a test add a label INTO the scroll view and see how it goes. If you need any more help I could through an xCode 4 project together for you... – Allison Mar 14 '12 at 13:10
  • Doesn't work either when I delete the image view and work with labels on scroll view directly. Well... if you have a Xcode project handy doing what I want to accomplish here I'm happy to take a look at it. –  Mar 14 '12 at 13:19
  • You can see in the storyBoard that he already has that checked. – coolcool1994 Jul 07 '13 at 00:39
0
CGRect scrollViewFrame = CGRectMake(0, 0, 320, 400);
self.scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];

[self.view addSubview:self.scrollView];
CGSize scrollViewContentSize = CGSizeMake(320, 400);
[self.scrollView setContentSize:scrollViewContentSize];
scrollView.delegate = self;

[self.scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];

scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;

NSUInteger nimages = 0;
CGFloat cx = 0;
for (; ; nimages++) {
    NSString *imageName = [NSString stringWithFormat:@"image%d.jpg", (nimages + 1)];
    UIImage *image = [UIImage imageNamed:imageName];
    if (image == nil) {
        break;
    }
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

    CGRect rect = imageView.frame;
    rect.size.height = image.size.height;
    rect.size.width = image.size.width;
    rect.origin.x = ((scrollView.frame.size.width - image.size.width) / 2) + cx;
    rect.origin.y = ((scrollView.frame.size.height - image.size.height) / 2);

    imageView.frame = rect;

    [scrollView addSubview:imageView];
    [imageView release];

    cx += scrollView.frame.size.width;
}


[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
codercat
  • 22,873
  • 9
  • 61
  • 85
0

Assuming that scrollView is a subview of view and fills it entirely you can use the following in viewDidLoad:

  [scrollView setContentSize: CGSizeMake(self.view.frame.size.width, self.view.frame.size.height)];

I had a UIScrollView that was not scrolling and this allowed it to scroll.

charles young
  • 2,269
  • 2
  • 23
  • 38
0

I had the same issue and was looking for the answer in this thread. I tried all the stuff, but nothing works. Then I found this:

deselect Use Auto Layout.

You just need to deselect "Use Auto Layout" in File Inspector of your ViewController. Ta-Da, it works immediately for me. Enjoy.

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
Watsche
  • 438
  • 2
  • 13
0

Just add code

scrollView.contentSize = CGSizeMake(WIDTH,HEIGHT);

to method -(void)viewDidLayoutSubviews. For more information checkout Stanford CS193p Lecture No 8 to understand View Controller Life cycle.

iOS_Dev
  • 26
  • 6