I made a scrollview in my storyboard which contains severals UIImageView.
The problem is, the frame of that scrollview is equal to {0, 0, 0, 0} and I don't know why. The scrollview is visible on my screen, but I'm not able to scroll it.
I already try to set a content size, and a frame, but without success.
Fixed it out !
In fact, I develop the app on iOS 6.0 and I had to uncheck the "use autolayout" checkbox on storyboard properties...
Thanks to all anyway !
I was getting this problem too but I need to use auto layout.
I was trying to set an UIImageView as a subview then do some calcs to work out the minimum, maximum zoom scales and set the zoomScale.
The problem was that I was trying to set zoomScale to zero as the scroll views frame was zero which was giving me this error:
<Error>: CGAffineTransformInvert: singular matrix.
So I setup the image and imageView in viewDidLoad / viewWillAppear (and hide the imageView) and then set the zoomScale in viewDidAppear (then unhide imageView).
This seems to work well, although I can't say for sure why. I guess it gives the scroll view a chance to set its bounds correctly.
The issue here is AutoLayout, as some of the other answers have indicated. Specifically, the issue is that autolayout does not occur until after viewWillAppear, and if you put your code in viewDidAppear, you will get funky display artifacts as you change things on the screen while the user is watching...
If you need AutoLayout enabled, the best place to put your frame dependent code is in:
- (void)viewDidLayoutSubviews
Keep in mind that this gets called again and again though, so if you only want some initialization code run once, when the view is displayed, then you can create a BOOL property that stores whether the initial layout has already been done.
#property (assign, nonatomic) BOOL initialLayoutComplete;
And then you can write your viewDidLayoutSubviews this way:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
if (!self.initialLayoutComplete) {
// frame dependent code here...
}
}
As I mentioned in this answer: The frame of the scrollview will not be initialised until you are in the viewWillAppear method.
This seems to be a new behaviour in iOS 6, not sure if it's a bug or an intentional change.
You should be able to use auto layout without worrying about this.
Did you connect IBOutlet?
Did you init scrollView with this code:
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 280, 360)];
self.scrollView.contentSize = CGSizeMake(500, 360);
//values are of course only example values
How you add UIImageView to scrollView?
I think one clarification is in place to Enrico comment below.
The frame size will have the right values at viewDidAppear (and in viewWillAppear the value will be set, but they are still zero in that method)
Related
I feel like I have touched on every single possible cause for stopping this, but I have a UIScrollView in my Storyboard hooked up with an outlet and in the viewDidLoad I set the contentSize so that I can scroll (yes bigger than my frame size)!
However, whatever I change, I just can't scroll! I have a couple of textfields in my scrollview and bouncing enabled so I can see that when testing its moves up and down with my subviews in it but whatever I set the contentSize to I just can't scroll.
Anything I might be missing/should check? Is this a known issue with UIScrollView being used in a storyboard?
Whats even stranger is, I can do something like this:
[scrollView setBackgroundColor:[UIColor blueColor]]; and I have a blue scroll view! But setting content size fails.
Edit
My only code (otherwise scrollview is just dropped into storyboard view controller):
-(void)viewDidAppear:(BOOL)animated
{
[scrollView setContentSize:CGSizeMake(320, 640)];
}
Logged frame, comes out as expected:
width: 320.00
height: 504.00
Edit 2
Turns out that removing any subviews of the scroll view in my storyboard lets it scroll just fine. If I add any subview to it at all via the storyboard, even a blank brand new UIButton it just won't apply the contentSize/allow scrolling.
use ViewDidLayoutSubview
- (void)viewDidLayoutSubviews
{
[_scrollView setContentSize:CGSizeMake(320, 500)];
}
UIViewController's method invoke sequence is as below
awakeFromNib
viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear
viewDidLoad is not a good place to put code that relies on frame sizes of IB objects. If you log the contentSize of your scroll view in viewDidLoad, you will see that it's (0,0). Move the code (where you set the content size) to viewDidAppear, and it will work properly.
Check these
User Interaction enabled
Outlet connected
Included contentsize greater than bounds
scrolling Enabled
eg
scrollView.contentSize = CGSizeMake(320, 640);
My storyboard looks like this for scrollview [working]
I had exactly the same line of code in viewDidAppear and it did not work
Moved it to viewDidLayoutSubviews and it worked correctly.
[scrollView setContentSize:CGSizeMake(320, 500)];
Thanks trick14 for the answer.
The issue is most probably with Auto Layout. UIScrollView needs special attention when using AutoLayout.
Quick-fix - bind one of the scroll's subviews to the top AND bottom space of it's superview (the scroll view).
Long story:
Questions on SO:
UIScrollView not scrolling regardless of large contentSize,
UIScrollView will not scroll, even after content size set,
UIScrollView doesn't use autolayout constraints
Apple's Documentation:
https://developer.apple.com/library/ios/technotes/tn2154/_index.html
Trip14's answer worked for me. In swift I coded it as:
override func viewDidLayoutSubviews() {
(self.view as! UIScrollView).contentSize = CGSizeMake(600, 600)
}
This seems to be a similar issue. Other Story
It might be an issue with auto layout or constraints in the storyboard.
the best way with the storyboard.:
I am working on very small app. In this app I am using UIrootviewController's table view to display some content in it. I want that content to be displayed at particular position so I am setting its contentInset. when I do it in viewDidLoad or in xib it is not showing any effect at first time. I have written it in shouldAutorotateToInterfaceOrientation function it is giving me proper location after orientation change but at first time it is showing table content at same location whatever may be the content insets values
here is my code for setting content insets
self.tableView.contentInset = UIEdgeInsetsMake(120, 150, 0.0, 0.0);
I have wrote this code inside viewDidLoad, and shouldAutorotateToInterfaceOrientation
but it is not showing any effect when application starts. is there any other method to achieve this.
i even tried setFrame, but did not worked.
I think you may be confused about what method to use. If you want to set the position and size of the view you should set its frame.
Put your code in the viewWillAppear method.
Try the following in viewDidLoad or viewWillAppear:
self.tableView.contentInset = UIEdgeInsetsMake(120.0f, 150.0f, -120.0f, -150.0f);
Im developing an iPad app in which I have a scrollview, the size of which i determine dynamically depending on the number of objects i display in it. Now, though i have not set any content offset I find that the scroll view has been offset by some amount whenever the view loads. When I check the value of the offset, it shows 0. I dont understand why without having a contentOffset value, the scrollview behaves that way. Any reasons for this?
I suspect this has something to do with iOS 4.2 as i dont remember this problem occurring when i was testing the app on iOS 3.2.
Update: The amount its getting offset seems to vary based on the contentSize of the scrollView. If the contentSize of the scrollView matches that of its frame height (its a vertical scrollview), then there is no offset. As the contentSize increases above the value of the height of the scrollView frame, the offset also increases proportionally. However, scrollView.contentOffset.y still = 0.0
if u use interface builder -
add scrollview to the view
create another view and add elements that u need to add to scroll view
then add this second view to scrollview
write this code in Viewdidload
scrollview.contentsize.y = lastelement.frame.origin.y + lastelement.frame.size.height + 10
this will adjust the scrollview to content size. it displays the first element and can scroll from top to bottom.
The UIScrollView definitively does not behave the same way on iPad with iOS 4.2.1 than in iOS 3.
I don't yet know if it's a bug or if I missed something in the documentation about an evolution.
My scrollview was created in a xib and I was reusing it to display different object of the same class. In my code, I only modified the contentSize of this scrollview.
The offset remained at 0 when looking with NSLog, but was varying on screen.
To fix my problem, I ended up creating programmatically a new scrollview each time I was displaying a new object. Might not be possible in your case, but for me, problem solved worked around.
I faced same problem. Solved by keeping code for setting scrollview in viewWillAppear:animated
-(void) viewWillAppear:(BOOL)animated
{
scrollView.frame = self.view.frame;
scrollView.contentSize = self.view.frame.size;
}
If you use Auto Layout and want to set the offset for the scroll view contents, this is what worked for me:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.myScrollView.contentOffset = CGPointMake(500, 0);
}
Assign the sum of frame.origin value and frame.height value of last element to scrollView.contentOffset.y
Also in Swift
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentOffset = CGPointZero
}
I have a UIScrollView contained within a custom UIView with a content size larger than the ScrollView's frame.
I am able to drag scroll as I expect, but the thing doesn't give me the rubber banding effect that you get with the UITableView or UIWebView. It just stops when you get to one of the extremes.
I have set bounce = YES, is there something else I'm supposed to do?
I read the docs, and they say I have to implement the delegate. I did that.
They also say I should change the zoom levels, but I don't want the user to actually be able to zoom so I haven't set these.
For anyone that finds this thread later, if you are subclassing UIView and re-setting the UIScrollView's frame on every layoutSubviews, that is the problem - it cancels the bounce:
http://openradar.appspot.com/8045239
You should do something similar to this:
- (void)layoutSubviews;
{
[super layoutSubviews];
CGRect frame = [self calculateScrollViewFrame];
if (!CGRectEqualToRect(frame, self.scrollView.frame))
self.scrollView.frame = frame;
}
I had the same problem, on a UIScrollView that wasn't all filled up (but I still wanted it to bounce). Just setted:
scroll.alwaysBounceVertical/Horizontal = YES;
And it worked as expected
It turns out that keeping the UIScrollView within my custom UIView was causing the trouble.
Once I switched my custom UIView to instead inherit from UIScrollView, then the bouncing started working.
That is interesting... Is there a lot going on while the user scrolls the scroll view? Maybe that could cause the problem. The iPhone can multitask, but not too much. Can I see your entire code having to do with the scroll view?
I have a subclass of UIView that I've added to as the titleView of a navigationItem using the following line of code:
self.navigationItem.titleView = tempview;
Easy enough. That works fine. My problem is that this navigationItem sometimes has the rightBarButton updated (sometimes there is no button, sometimes there is one standard sized button, sometimes there is a larger button).
I figured that I could simply use the layoutSubviews method of the tempview class that I've added as the titleView so I put this in:
-(void)layoutSubviews {
[super layoutSubviews];
self.mylabel.frame = self.bounds;
}
This does not seem to work, as it does not correctly resize the titleview when the rightBarButton item is updated.
I've noticed also that the bounds do not grow once they gotten smaller, they simply change the position.
I've tried using setNeedsLayout and layoutIfNeeded but those simply "resize" the view with the incorrect bounds.
I've also made sure that the rightBarButton item is set to nil, but the view still does not correctly expand once shrunk.
Thanks for any help!
configure your view with
[self setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];
(probably in the initWithFrame)
then implement
- (void)willMoveToSuperview:(UIView *)newSuperview
{
[self setFrame:[newSuperview bounds]];
}
now you have your view matching the size of the container, and resizing automatically.
By default, layoutSubviews does nothing. You also never change the size of the titleView, so unless a navbar does that for you, it's no surprise that nothing is changing.
Since you're only changing the size of one of the subviews, I don't think autoresize will work, as I'm pretty sure it's triggered when the superview (the one with autoresizesubviews enabled) changes size. I would suggest recalculating the size of the titleview when you change the rightbutton. If it automatically fits when you add it the first time, you could remove and readd it, but I know that's a pretty ugly hack.
Instead of overriding -layoutSubviews have you tried setting the autoresizingMask property?
tempView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;