I have a scrollview that is working in iOS8, but not in iOS7. My xib file has the scrollview outside the main view. I add the scrollview to the view with:
helpScrollView.contentSize = helpScrollView.frame.size;
helpScrollView.frame = self.view.frame;
[self.view addSubview:helpScrollView];
I have confirmed by printing the values to the console that the content size after this is 320x670 and the frame size of the window to be 320x568. However, in iOS7, the scrollview won't scroll even though the content is cut off. It will scroll as expected in iOS8. The scrollview contains a multiline label that fills the scrollview. I am getting a warning for "Automatic Preferred Max Layout is not available" so that could be related. Any help would be great!
Joseph
It work for me,
"For some reason, viewDidLoad is too early in the life cycle to obtain the scroll view's adjusted frame on iOS 8, but again it works on iOS 7. viewWillAppear is also too early, as well as viewWillLayoutSubviews.
To solve the problem, I just moved the code where I need to use the scroll view's frame size to viewDidLayoutSubviews which does finally obtain the correct size it will be when it appears."
UIScrollView frame is a different size on iOS 8 vs iOS 7
Related
I have a Swift app which sets a UIImageView to the size of a portion of the screen (set with autoconstraints to the margins and controls above it), and I use the height and width values of the ImageView to create 3 additional UIImageViews programmatically and position them on top of the original image. I am constructing a podium and place three images on top of the podium in appropriate positions. I then calculate the height and width of each additional image by creating a constant: let conImageHeight = 0.4 * self.imgPodium.frame.height. However, I can't get a reliable height and width of the original image.
Initially I used self.imgPodium.bounds.height which worked great for the iPhone 6 simulator screen size, but when I tried running the app on an iPad simulator, it kept the iPhone size values. The image itself changed size but when I println() the height and width using bounds, I get the values of the iPhone image.
I then changed and used self.imgPodium.frame.height but this didn't change anything.
Is there a better way to get the height and width of a UIImageView (or any control for that matter) after it positions itself through autoconstraints?
Thanks.
Questions I've looked at already but didn't help:
Change UIImageView size and position programmatically in Swift
how to check screen size of iphone 4 and iphone 5 programmatically in swift
UIImageView Bounds, Frame
Cocoa: What's the difference between the frame and the bounds?
How to resize an UIImageView (swift)
In viewDidLoad the subviews have been loaded and initialized but not layed out yet. Therefore their frame property for example is not valid yet and may be the one that was set in Xcode when designing the UI in the first place - that however is not reliable. You should do custom layout in places where you can be sure the layout has already happened yet: e.g in viewWillLayoutSubviews or viewDidLayoutSubviews. Both methods will also get called when the layout somehow needs to change. In viewDidAppear the layout has been done yet and therefore you can do some layouting too. This code however will get not get called when the layout changes due to interface rotation for example. AND it will get called after a presented viewController gets dismissed again. (not what you would want).
In both cases: do your setup of creating new imageViews in viewDidLoad and do the layout in viewWillLayoutSubviews or viewDidLayoutSubviews!
I'm in the midst of developing an app for the iPhone and iPad. It supports iOS6 and iOS7 and it uses auto layout exclusively.
This past week, when Apple announced that iOS8 was ready for prime-time, I upgraded one of my iPhones and an iPad both to iOS8. I also bumped my XCODE up to version 6. I have 2nd iPhone which I left at iOS7.
I generated new executables with Xcode 6 and I was distressed to see that their screen layouts were messed up when executed on my devices running iOS8 but still fine on iOS7. This is true on both my physical devices and on Xcode's emulators.
It took a lot of digging but I'm pretty clear now on what's happening though I don't know why.
Specifically, certain auto layout operations are failing for me on iOS8 but they are fine on iOS7.
Some examples involving a button which I am placing on an underlying view whose size is equal to the size of the screen:
(1) If I ask auto layout to position the button's horizontal center (CX) equal to the underlying view's horizontal center, the result is that the button's horizontal center is placed on the underlying view's left edge.
(2) If I ask auto layout to to make the width of the button equal to 50% of the width of the underlying view, it gives it no width at all.
I am able to work around these issues as follows:
(1) I ask auto layout to position the button's center equal to the underlying view's left edge plus 50% of the screen's width.
(2) I ask auto layout to make the button's width equal to 50% of the screen's width.
I am slowly clawing my way, with workarounds like these, back to auto layout code that works for me on both iOS7 and iOS8. But I am really wondering what's going on here.
It looks like auto layout cannot determine the size of the underlying view and so auto layout calculations that require that information fail. But it does know where the top and left edges of the view are so calculations based on those data succeed.
This is a large app and I've written many hundreds of lines of auto layout code for iOS6 and iOS7 that work perfectly for me.
I've been tweaking and trying things now with iOS8 for three days and I'm no wiser than I was when I began.
Anyone have any suggestions or thoughts as to what might be the issue here?
#robmayoff has a great answer for this: https://stackoverflow.com/a/26066992/1424669
Essentially, in iOS8 you can no longer call setNeedsUpdateConstraints and setNeedsLayout on a view and expect the constraints of subviews to update.
You must call these methods on the view whose constraint is changing. This is backwards compatible to iOS7.
EXAMPLE:
Suppose you have a ViewController with root view self.view and a subview called containerView. containerView has a NSLayoutConstraint attached to it that you want to change (in this case, top space).
In iOS7 you could update all constraints in a VC by requesting a new layout for the root view:
self.containerView_TopSpace.constant = 0;
[self.view setNeedsUpdateConstraints];
[self.view setNeedsLayout];
In iOS8 you need to request layouts on the containerView:
self.containerView_TopSpace.constant = 0;
[self.containerView setNeedsUpdateConstraints];
[self.containerView setNeedsLayout];
You might find the answers to this question helpful: UICollectionView cell subviews do not resize
In most cases the works in iOS7 but not on iOS 8 auto layout problems seem to stem from the root view not being sized correctly in iOS 8, particularly when we set translatesAutoresizingMaskIntoConstraints to NO. For my views I was able to set the root view's frame in layoutSubviews (or whichever appropriate initializer that does have the correct bounds) and this resolved the issue.
self.contentView.frame = CGRectInset(self.bounds, 0, 0);
As shown in the answer above, you could also do
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
and then turn translatesAutoresizingMaskIntoConstraints back to NO before you start setting your own constraints in code.
Definitely hate that so much of our time is taken with these annoying gotchas.
In my case, the problem related to constraints labeled UIView-Encapsulated-Layout-Width and UIView-Encapsulated-Layout-Height. When I removed them, everything behaved as though my view was of zero size, with everything centered on the upper left corner of the screen. When I left them in, new constraints worked as expected. I also retained the constraints labeled _UILayoutSupportConstraint.
At first, I am facing a strange problem with a UIScrollView with Pagin enable but only on iPhone 4 and iOS 7.
So the idea is that I have a UIScrollView (A) containing a UIView (B) that has subviews (Cs)
It's working perfectly on iPhone 5 screen size, for both iOS 7 and 8.
It's working perfectly on iPhone 4 with iOS 8.
It's not working properly on iPhone 4 iOS 7.x
After hours of logging, here is the problem :
UIScrollView A frame height : 480 <- EDIT : this was sometimes 480, sometimes 568
UIScrollView A content size : 960
UIView B frame height : 960
The first page is displaying properly.
When scrolling down to the second page, UIScrollView A contentOffset is 392, instead of the expected 480, so that there is not way to see the bottom of the second page, and bottom of the first page is still visible at the top of the second page.
So the question is : How does iOS find the page size ?
Any help will be appreciated !
The page size is the size of the scroll view. It sounds like the issue is that the height of the content is not defined correctly. If you are using auto layout you need to make sure that the constraints are set up properly. Otherwise you can set the size of the content programmatically.
Either way checking programatically what the content size of the view is should confirm if this is the issue.
When running in Xcode 6 you can examine the views on the screen more carefully using this button:
found here:
when your code is running and you are on the correct view
I finally get it by removing the UIScrollView bottom constraint and replace it with a height constraint, setting it to the superview height at run time.
It seems that the scroll view paging size is just correctly evaluated, but may scrollview was too big for the screen.
I am having a very frustrating issue. I know there are all kinds of issues with UIScrollView in iOS7 and XCode 5. I need to implement a scrollview and there are all kinds of tutorials showing you how to do it by switching off auto layout but that then messes with the rest of the views in my app.
I tried the fix of putting my subviews into a container UIView and placing that in the UIScrollView and setting the scrollview's content size to the size of the contained UIVIew. That didn't work. Now I am working with placing everything in the scrollview and it all works with one exception. When I load the view on the simulator or a device the content view is moved down but somewhere around 60 points or so. See image below.
That white space below the title bar on the right is still the scroll view as I can press and drag within it. Adjusting the contentOffset doesn't do any good as that just scrolls the view down slightly. I have no idea what to do here.
Just a little more info: I setup the scrollview and all the subviews in storyboard and the connected them up. Not sure if that has any bearing on it.
Thanks in advance for any help you can provide.
I think your Scrollview top space constraint have 64 pixels. That's a problem. So, set your top space constraint value to 0.
You need to add the constraints before view displayed then contentsize will be set automatically.
Check UIScrollView's autoresizing mask. It has to be set like this.
In my UIViewController I have a UIScrollView and UIView. These are two different view, means UIView is not inside UIScrollView. I have different view on scrollview that i am setting programmatically and increasing contentSize. And this UIView is hidden, i am showing is sometimes. The problem is that when i hide this UIView, that UIScrollView stops scrolling.
Why this happening?
I have set all leading edges to superview of both. Does it matter?
Please guide me.
Hi all, I am sharing the image of my ViewController Scene
I am using auto layout (iOS6). Scroll View ContentSize is (768,1400) which i am setting in ViewDidAppear. The View below Scroll View is hidden and Scroll View is scrolling without any problem.
Now if i show and hide the View, the Scroll View locks, its not scrollable now.
That is problem i am facing.
I am not doing anything in code more than setting content size.
If you need any other information, please tell me.
The contentSize in iOS 6 "auto-sizes" itself with auto layout. This means you cannot set the contentSize. There are hacks that suggest setting it in the viewDidAppear call, but I would avoid this. If you read the iOS 6 release notes (search for UIScrollView on the page) it gives you a couple solutions. One of them involve the translatesAutoresizingMaskIntoConstraints property.
Remove all your code related to sizing the scrollview content size. Autolayout uses this while you are scrolling now. After you do this add the following code
// Add 200 points to the bottom of the scroll view
[self.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 200, 0)];
self.scrollView.translatesAutoresizingMaskIntoConstraints= NO;
Without any code, I'll hazard a guess...
This would be typical in a case if your contentSize doesn't exceed the size of your UIScrollView. If you were to, say, hide your view, then change the size of your scroll view and your scroll view exceeds or is equal to your contentSize, then you will not have anything to scroll.
Another possibility is if you have disabled user interaction.