I have a UIScrollView
which contains many UIImageView
s, UILabels, etc... the labels are much longer that the UIScrollView
, but when I run the app, I cannot click and scroll down...
Why might this be?
Thanks
This question is related to
ios
iphone
ipad
uiscrollview
Uncheck 'Use Autolayout' did the trick for me.
Environment: xCode 5.0.2 Storyboards ios7
After failing with the provided answers in this thread, I stumbled upon this article with the solution.
There are two things not intuitive about setting up the scrollview with autolayout:
This is the gist of that article. For a complete explanation, including illustrations, check it out.
yet another fun case:
scrollview.superview.userInteractionEnabled must be true
I wasted 2+hrs chasing this just to figure out the parent is UIImageView which, naturally, has userInteractionEnabled == false
I made it working at my first try. With auto layout and everything, no additional code. Then a collection view went banana, crashing at run time, I couldn't find what was wrong, so I deleted and recreated it (I am using Xcode 10 Beta 4. It felt like a bug) and then the scrolling was gone. The Collection view worked again, though!
Many hours later.. this is what fixed it for me. I had the following layout:
UIView
It's all in the constraints. Safe Area is automatically defined by the system. In the worst case remove all constraints for scroll and content views and do not have IB resetting/creating them for you. Make them manually, it works.
basically the concept is to have Content view fitting Scrollview, which is fitting Safe Area.
But as such it didn't work. Content view missed the height. I tried all I could and the only one doing the trick has been a Content view height created control-dragging Content view.. to itself. That defined a fixed height, which value has been computed from the Size of the the view controller (defined as freeform, longer than the real display, to containing all my subviews) and finally it worked again!
Something that wasn't mentioned before!
Make sure your outlet was correctly connected to the scrollView! It should have a filled circle, but even if you have filled circle, scrollView may not been connected - so double check! Hover over the circle and see if the actual scrollview gets highlighted! (This was a case for me)
//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
The idea of why scroll view is not scrolling because you set the content size for scrolling less than the size of the scroll view, which is wrong. You should set the content size bigger than the size of your scroll view to navigate through it while scrolling.
The same idea with zooming, you set the min and max value for zooming which will applied through zooming action.
welcome :)
You need to set the contentSize
property of the scroll view in order for it to scroll properly.
If you're using autolayout, you need to set contentSize
in viewDidLayoutSubviews
in order for it to be applied after the autolayout completes.
The code could look like this:
-(void)viewDidLayoutSubviews
{
// The scrollview needs to know the content size for it to work correctly
self.scrollView.contentSize = CGSizeMake(
self.scrollContent.frame.size.width,
self.scrollContent.frame.size.height + 300
);
}
I found that with this AutoLayout issue... if I just make the ViewController
use UIView
instead of UIScrollView
for the class... then just add a UIScrollView
myself... that it works.
If none of the other solutions work for you, double check that your scroll view actually is a UIScrollView
in Interface Builder.
At some point in the last few days, my UIScrollView
spontaneously changed type to a UIView
, even though its class said UIScrollView
in the inspector. I'm using Xcode 5.1 (5B130a)
.
You can either create a new scroll view and copy the measurements, settings and constraints from the old view, or you can manually change your view to a UIScrollView
in the xib
file. I did a compare and found the following differences:
Original:
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>
After type spontaneously changed:
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>
So I replaced the <view>
line with my original <scrollView>
line.
I also replaced the view's close tag </view>
with </scrollView>
.
Be sure to keep the id the same as the current view, in this case: id="qRn-TP-cXd".
I also had to flush the xib from Xcode's cache by deleting the app's derived data:
Xcode->Window->Organizer->Projects
, choose your project, on the Derived Data line, click Delete...Or if using a device:
Xcode->Window->Organizer->Device
, choose your device->Applications, choose your app, click (-)Now clean the project, and remove the app from the simulator/device:
Xcode->Product->Clean
Simulator/device->press
and hold the app->click
the (X) to remove itYou should then be able to build and run your app and have scrolling functionality again.
P.S. I didn't have to set the scroll view's content size in viewDidLayoutSubviews
or turn off auto layout, but YMMV.
One small addition, all above are the actual reasons why your scroll view might not be scrolling but sometimes mindlessly this could be the reason specially when scrollview is added through code and not IB, you might have added your subviews to the parent view and not to the scrollview this causes the subview to not scroll
and do keep the content size set and bigger than parent view frame (duhh!!)
Make sure you have the contentSize property of the scroll view set to the correct size (ie, one large enough to encompass all your content.)
If you cannot scroll the view even after you set contentSize correctly, make sure you uncheck "Use AutoLayout" in Interface Builder -> File Inspector.
The answer above is correct - to make scrolling happen, it's necessary to set the content size.
If you're using interface builder a neat way to do this is with user defined runtime attributes. Eg:
Add the UIScrollViewDelegate
and adding the following code to the viewDidAppear
method fixed it for me.
@interface testScrollViewController () <UIScrollViewDelegate>
-(void)viewDidAppear:(BOOL)animated {
self.scrollView.delegate = self;
self.scrollView.scrollEnabled = YES;
self.scrollView.contentSize = CGSizeMake(375, 800);
}
Try to resize the content size to huge numbers. I couldn't understand why my scroll view doesn't scroll even when its content size seems to be bigger than control size. I discovered that if the content size is smaller than needed, it doesn't work also.
self.scrollView.contentSize = CGSizeMake(2000, 2000);
Instead of 2000 you can put your own big numbers. And if it works, it means that your content size is not big enough when you resize.
The delegate is not necessary for scroll view to work.
if you are getting a message (IOS8 / swift) that viewDidLayoutSubviews
does not exist, use the following instead
override func viewDidAppear(animated: Bool)
This fixed it for me
I had the same issue in IB.
After setting the leading, trailing, top and bottom of the scrollView to its superView. I made the following changes to make the containerView scrollable, which worked.
To make the scrollView only scroll on horizontal direction make the constraint with scrollView's centerY = ContainerView's centerY
and to make it vertically scrollable make the scrollView's centerX = ContainerView's centerX
adding the following code in viewDidLayoutSubviews
worked for me with Autolayout. After trying all the answers:
- (void)viewDidLayoutSubviews
{
self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);
}
//set the height of content size as required
Set contentSize
property of UIScrollview
in ViewDidLayoutSubviews
method. Something like this
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}
My issue was resolved by:
Once I removed top and/or bottom constraints bound to the safe area and/or superview, the views inside the scrollView could scroll again and didn't stay fixed to the top of bottom of the screen!
Hope this stops someone else from hours of pain with this particular issue.
In my case I had to set delaysContentTouches
to true because the objects inside the scrollView were all capturing the touch events and handling themselves rather than letting the scrollView itself handle it.
Alot of the time the code is correct if you have followed a tutorial but what many beginners do not know is that the scrollView is NOT going to scroll normally through the simulator. It is suppose to scroll only when you press down on the mousepad and simultaneously scroll. Many Experienced XCode/Swift/Obj-C users are so use to doing this and so they do not know how it could possibly be overlooked by beginners. Ciao :-)
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
// Do any additional setup after the view
}
override func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
scrollView.contentSize = CGSize(width: 375, height: 800)
}
This code will work perfectly fine as long as you do what I said up above
If your scrollView
is a subview of a containerView
of some type, then make sure that your scrollView
is within the frame or bounds of the containerView
. I had containerView.clipsToBounds = NO
which still allowed me see the scrollView, but because scrollView
wasn't within the bounds of containerView
it wouldn't detect touch events.
For example:
containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;
You will be able to see the scrollView but it won't receive user interactions.
Source: Stackoverflow.com