UIScrollview with size class and auto layout selected - ios

In my app, I am using standard xib files rather than a storyboard and all of the views have the universal size class option selected. When I do the design work, I always work in the any.any frame.
All views are set to use auto layout and size classes.
For just about everything, this works a treat.
The problem comes if I have a UIScrollView in the view. It looks fine in any,any and when I move to compact,any the view looks fine with everything in the right place.
However, if I then test on the device, the scrollview is much larger than the device view, so something has gone amiss.
Adding in scrlView.TranslatesAutoresizingMaskIntoConstraints = true; sorts the problem for the scrollview, but then messes up the rest of the view outside of the scrollview.
The scrollview is set to have scrolling enabled and bounces. Everything else is as it comes when you add the scrollview.
It looks as if the scrollview (on deployment) is set to still be any,any rather than compact,any.
Is there a way to fix this?

Related

Xcode embed all direct in scrollview without content view

I'm using Xcode 6.4 and I'm struggling with a large page with a bunch of various labels and text fields etc., that has to be scrollable. I looked at various tutorials some of which are obviously outdated and I had all my elements at first in a view that is inside of a scroll view. But that was a big pain with getting all the elements aligned properly using Auto Layout, in addition to not getting it to scroll either.
Now I see one person recommend using the following directly on the elements, without having a content view at all just a scroll view:
Editor -> Embed In -> Scroll View
I like it for the fact that nothing seems out of proportion, all the elements are shown on the iPhone exactly as I have it on the Storyboard without having to set any constraints, however I'm not able to get it to scroll.
This is my class
class ResNotFoundViewController: UIViewController, UIScrollViewDelegate
and I also try to set the height of the scrollview in the code as so:
#IBOutlet weak var scrollviewoutlet: UIScrollView!
and then this in the viewDidLoad as so:
scrollviewoutlet.contentSize = CGSizeMake(375, 840)
.
But I'm not able to get it to scroll at all, it will stay exactly like it opens up with From: Label being the last visible elements.
What am I doing wrong?
You've located the problem, thanks to your logging. (Don't worry about the double call - how many times and when viewDidLayoutSubviews gets called is uninteresting.)
The problem is that you've set the scroll view itself to be taller than the window. In particular, it is 375x809. But so is its contentSize. Thus there is nothing to scroll. A scroll view can only scroll if its contentSize is bigger (in one or two dimensions) than the scroll view. (Moreover, a scroll view bigger than the screen is usually somewhat pointless, since there will be parts of its content that the user will never see - even scrolled all the way, that content will be offscreen.)
So, fix the size of the scroll view itself and you'll be fine. The best way is to assign it constraints that pin its boundaries to its superview, since the superview will have different sizes on different devices.

Weird behavior with Auto Layout and UIScrollView paging

I'm trying to have a horizontally scrolling UIScrollView with horizontal paging (kinda like a UIPageController but managed by a single UIViewController)
Because I'm using Auto Layout I have set up everything by using constraints for the views inside, and the scrollview works just fine. However what is odd is that the paging works in a weird way.
Specifically the scrolling becomes really slow and it takes over 5 seconds for the scroll view to snap in place.
I am absolutely puzzled by this because I have done this before with a smaller view (about three "pages" as opposed to 6) and it worked flawlessly.
I have created a sample project to illustrate this; just build it and try scrolling left and right - it works best if you just flick once.
http://mbx.cm/t/MmLIi
The only thing that seems to prevent this is having the viewcontroller manage the scrollview directly (as opposed to have it inside a UIView), but I'm sure the problem lies elsewhere so I figured I'd try my luck to see if any Auto Layout gurus can help me out on this one.
All I did was change your view controller's "Simulated Size" to "Fixed" instead of "Freeform" in the storyboard and it worked fine after that. Not really sure why that would change anything, but it did!

iOS: How can I prevent a resized view from resetting itself?

I'm using ECSlidingViewController. When the app starts, it opens a scroll view which is resized dynamically, since it contains both labels and a table view. Both the table and the scroll view containing it are resized.
Everything works as intended when the view is first loaded. However, if I open and close the menu view, or if I use it to go to any view which resizes itself, the resizing does not work. Instead, it displays the scroll view as if it has the height assigned to it in the storyboard.
I'm completely lost as to why this happens, and would greatly appreciate help. I can post code as well, of course, but I don't know what code might help, since I guess that the error is on ECSlidingViewController's part.
Are you using auto layout? If so, whenever something else happens that triggers the application of the constraints, all the frames will be reset to the values dictated by those constraints. Try turning off auto layout and see if that fixes it. Refer to your auto layout settings.
Alternatively, if you want to keep auto layout, I'd generally suggest changing the frames by programmatically changing the constant values of the constraints. But, I'm not familiar with ECSlidingViewController, so I don't know if that's a reasonable option in this particular case.

Using UIScrollview in iphone5 compatible app

I have a problem adapting my apps to the new iphone5 layout, I've made the following passes:
Added a retina 4" splash image
Modified the interface in my storyboard with "Size inspector" to change the anchoring of the widgets
Tested the app with iOS6 "retina 4" simulator.
The app works as expected except when the user pop up the keyboard to edit a text, I use the "stretching scrollview" method for this particular situation and this seems not compatibile with the "autosizing" properties of my widgets, here is an example, from iOS6 simulator, without and with keyboard:
And here is what happens:
I'm quite sure this is a coherent behaviour since my main view is stretched so the other items inside it are stretched following their anchoring, the fact is that I'd like to have the same behaviour of my previous fixed position (all widgets anchored to the top left corner) with the iphone5 gui expansion, is this possibile?
How do you solve the problem of showing a keyboard and scroll hidden content in an iphone 5 compatible way?
I have been having similar problems. From what I have found thus far, we may need to remove all constraints on the view within the scrollable view, because it appears that it's contents are being resized along with the frame of the scrollView. I know that setting the internal view's frame manually in viewWillAppear will work, but then you are stuck having a view that is the same size for both iPhone4 and iPhone5 (albeit it will scroll). Or you could "pin height and pin width" of the internalView right there in storyboard.
Two potential approaches that may work. Sorry I can't confirm these as I'm giving up and redesigning around this problem.
1. Programmatically add constraints to your internal view's subviews. The programmatic constraints will allow you to "spring" the distance between your elements proportionally. When adding constraints programmatically, you are given access to a factor called "multiplier" (not to be confused with priority), which I saw someone else on stackoverflow posting about.
2. You can design the internalView in Interface Builder as a separate viewController with it's .xib file, and then use storyboard to load it as an embedded viewController to a "containerView" object, which you would put in place as the new "internal view" of the scrollView. Perhaps then the .xib would first resize to the correct iOS device, and then you could use its frame to resize the containerView.
My advice is create a small test-case of these before implementing, else you end up like me, having spent hours down the wrong path and facing a dead-end.
UPDATE 12/4/12
Make your life easier by NOT setting the ScrollView as the main view of the ViewController.
--Instead, make ViewController.view a dummy/blank view, and embed a scrollView inside that view. Then, embed another view (my CustomView) in the ScrollView. CustomView contains all the visible controls and text boxes and buttons. There is NO HEIGHT CONSTRAINT on CustomView.

Designing inside a scrollview in xcode 4.2 with storyboards

I have a vertically scrolling uiscrollview - imagine an 'about this app' page of a tab bar app which goes on a bit and requires a scrollview. It only contains a few images, a video and some text (only the video has been coded in - the rest have been placed in the GUI). In storyboard (Interface Builder?) Xcode 4.2, everything is set up as it should be and works fine, but the view is only as large as what you see on the screen, is it not possible to manually arrange in storyboard the items that are initially offscreen - that you need to scroll up to? The only way I've found so far is to design them on the visible view then navigate them down with the arrow keys..
In the storyboard select the viewController, then in Attributes inspector change 'size' to 'freeform'. Then change the 'height' of the view/scroll view to as big as you need. The default settings of struts and springs should take care of resizing the view back correctly when the app is run, but you should double check.
I feel your pain. The only way I found is to manually pan the scroll view in the size inspector to reveal the portion of the view that you wish to visually edit.
Use a UIView to contain elements so they are positioned relatively to this view. Add the view as a subview to the scrollview at 0,0.
pan: use the Y coordinate say to -200, then edit the contents.
to place more contents in the hidden part, pan again to reveal new real-estate
when finished, restore the values of the ScrollView's height and X,Y position.
Make sure the scroll view frame rectangle is smaller than the contained view.
New: 3/26/2013
I stumbled upon what I think is even simpler way of dealing with UIScrollView directly in storyboard.
No code needed, just storyboard settings. This maybe new in iOS6.1 / Xcode 4.6
No need to disable constraints (i.e. uncheck "Use autolayout" in File Inspector for storyboard file)
No need to add UIScrollView* scrollView; in .h
No need to add self.scrollView.contentSize = ... in overrides of viewWillAppear or viewDidLoad
Here is what I did (important parts highlighted with **): (see code)
Create a new project with storyboard enabled
Drop in a UIScrollView, set class in identity inspector for view controller
In attributes Inspector, change Size under simulated metrics to Freeform**
Select scroll View; In attributes inspector, turn on "scroll enabled" and "background" to "White" (you'll figure out why - if you don't)
Under Size Inspector (with scroll view selected) change the height to 900 for example**
Add buttons, one on top and one at the bottom
Add a default handler for buttonTouchUpInside for both buttons and simply Log sender.
See Code Select the View Controller and scroll view and check inspectors.
Just change the 'Simulated Size' of the view controller to freeform and set a height that is larger than the usual size, you will be able to see all the outlets you need to edit.
On iOS 6.0 you can drag a Container View inside your Scroll View. This will automatically create a new View for your content, outside of the current scene. You can then resize this view as big as needed to fit your content.
I believe you would still have to set the ScrollView content height at runtime, but at least you can design you content view at once without having to scroll up and down on IB.
Just uncheck the "Autoresize subviews" from any view that you're trying to resize and it should keep all your objects from resizing with it.
I've been struggling with this for a while now, and every single thing I've tried has failed.
Specifically, What I am trying to achieve is a freeform sized modal dialog with a scrollable view containing a container for another view. I have had a lot of varied results, including occasionally having it working correctly. Most often I get it looking exactly correct, but with no scrolling.
In finally downloaded Dickey Singh's code, which worked perfectly but had nothing special. (Excellent clean solution BTW). So, I added a container view to it, exactly as I had in my code, and it broke!
After some experimenting, I worked out what is going on. Just bear with me.
1) Using Auto Layout, the size of the scroll view seems to dictate what the scrolling bounds will be. Setting "contentSize" in "USer Defined Runtime Attributes" seems to have no effect on this, and neither does setting "contentSize" or "bounds" in "viewWillDisplay" or "viewDidLoad". Thus if the initial size of the scroll view is 800x800, that will be all the space that can be displayed. For this reason, when I want a scrollable region, I create a container view and then put the scrolling view inside the content.
2) Without Auto Layout, setting "contentSize" in "User Defined Runtime Attributes" works, as does by setting it programmatically in "viewDidLoad". I prefer to use "User Defined Runtime Attributes" because it keeps the size with the layout. This solution allows you to use scrolling view with more flexibility, since it can be any size at design time.
3) Regardless of Auto Layout, if any view within the scrolling region exactly matches EITHER the horizontal or vertical frame bounds, then the scroll view ceases to function as a scroll view. This applies to my own code and to Dickey Singh's code in every possible configuration that I have tried.
I have no idea what is causing (3), but it is clearly a bug.
I hope this helps everybody out there who is struggling to use scroll view. I imagine that some people are using them without any problem, and some (like me) have had noting but problems with them.
Here's my solution to design a ScrollView with a content larger than the screen entirely in Storyboard (well, except for 1 single line of code :-) :
https://stackoverflow.com/a/19476991/1869369
I'm currently developing an app for iOS 7, and I did exactly as #Dickey Singh's answer, but it doesn't work in the beginning.
After checking the storyboard, I found that we also need to add Auto Layout Constraints for the view controller who holds the scrollView.
It seems that such auto layout constraints would be added automatically before Xcode 5, but now we need to do it ourselves.
The way to add constraints: First select the view controller in the storyboard; Enter 'Editor' in the top menu; Select the 'Resolve Auto Layout Issues'; Select the 'Add Missing Constraints In Container'. Done :-)

Resources