Mass auto layout option for 40 viewcontrollers? - ios

I designed about 40 view controllers using a 5.5 inch storyboard layout. After all of that I tested it on the iPhone 4S...big mistake. everything is jumbled together being for a larger screen size. I was able to fix one view controller up using Size Classes. I am wondering if there is any way I can adjust all 40 at the same time, or at least avoid doing this for every single one. It is really frustrating finding this out now. Thanks!

This is a relatively complicated issue you are attempting to solve, but I have two potential solutions. Both suggestions are based on moving your current interface into containing UIScrollView instances
If you are using storyboards, then for each of your view controller scenes, put a UIScrollView as a descendent of the view controller's view. From there, provided your subviews are contained within other views (like a container view for a set of buttons), you can move those into your scroll view. You will have to setup constraints to define the size of the scroll view's content, but this will allow the size of the device to have a smaller impact on the interface as you will get scrolling as needed.
If you are using nib files (.xib) then it is essentially the same thing, but easier. In this case, move a UIScrollView onto the canvas, but not as a subview of the default view. Once that is out there, move the original view to be a subview of the scroll view and set constraints to be 0 from the subview to the scroll view. Finally, right click drag from the File's Owner icon to the scroll view and set that as the view outlet.
Hopefully one of these will help you.

Related

iOS Auto Resizable Container Views

I am building an iOS app with multiple screens but I want avoid duplication of code as well as one large storyboard. Ideally I would like to load the various View Controllers based on a selected storyboard in my content view when needed.
The template of the screen (Master/Root View) shall be composed by 3 Views, namely:
View A that acts as a Navigation View,
View B where the various View Controllers should be loaded based on user actions and,
View C, much like a Tab bar or a 3rd View where I can display some
circumstantial information.
Now, of course I could go with a traditional UINavigationController and UITabBar but I need greater control over those views, notably in terms of size (they have minimum heights that are larger than the ones for NavBar and TabBar).
I also need those Views to resize based on the Traits and Class Size to keep filling the entire screen.
I am trying to use container views to doing so, but I can't get them to resize automatically despite having tried a different set of constraints in auto-layout. Putting the 3 views in a stackview does not do the trick either.
Ultimately I would like to be able to work separately on my various Controller Views that will be loaded in View B, using their own storyboards, calling them programmatically in B and having everything automatically resized.
Thank you all for your kind and valuable input!
Chris
When using addChildViewController(childVC) / addChild(childVC) (Swift 4.1 / 4.2), followed by myContainerView.addSubview(childVC.view) you need to either
add constraints for the added subview
or
set the frame of the subview and .autoResizingMask
After that, your newly added subview will layout and resize correctly.

Is it possible to set constraints for root view in XIB?

Recently i was following a tutorial to create frameworks in Swift, Where they create reusable visual effect view just like we see in Xcode build success pop up. I was doing the UI step by step where they created a new xib file and dragged and dropped UIVisualEffectView into it.
In the above image we can see that the UIVisualEffectView doesn't contain any constraints. It only has auto resizing masks in size inspector(as expected).
But the following image from the tutorial suddenly contains all necessary constraints for it's root view.
I'm already aware that we CANNOT, by default set any constraints for the root view. But in the tutorial the author seems to have added constraints for the same. I'm just curious to know if it is possible to do that or am i missing any fundamental idea ?
EDIT:
Constraints for root view.
OK, found one way to do this...
Haven't done any testing, so I'm not sure if the constraints are really set correctly or will be used by auto-layout at run-time, but this will put them there.
Create a new "View" XIB - this is how it looks to start:
Add a Visual Effect view to this view, and give it width and height constraints of 230 / 230:
Now, drag that Visual Effects view *out of the plain view, onto an empty space:
You will see it maintains its constraints. Then delete the original view, and add the other elements:
As you can actually see on your screenshot the width/height constraints belong to the View (first subview of Visual Effect View).
Look at the green line:
I don't know what's going on your tutorial (and I have no intention of watching it), and I have no idea under what circumstances the screen shot was achieved. But I do know the rules for how a view controller's main view gets sized.
Any view controller's main view must expect to be resized as it is placed into the interface. The size in the storyboard is therefore meaningless. That is why you cannot give it a size with auto layout.
If a view in a xib or storyboard is to be used as the main view of a view controller, it is meaningless (and would be wrong) to set constraints on it, because it will be the task of the view controller's parent (or, in the case of the window's rootViewController, of the window) to set the size of the view when it places it into the hierarchy.
If a view controller wants to vote on the size of its view when it is placed into the view hierarchy (for example, as a popover), that is what the content size (preferred explicit size) is for. But even then, the parent is the one who controls what actually happens.

UIScrollView and two-way scrolling

I'm having some trouble working with UIScrollView in my current project. My intention is to have a variable-size drawable canvas which can extend beyond both sides of the screen, and whose size is determined by the user at runtime. For this purpose, I put in a UIScrollView with a Content View inside of it in my View Controller. Unfortunately, Interface Builder keeps pestering me to define the X and Y axes of my Content View as a constant sizes which isn't possible given my specifications. I've even set the ScrollView.contentSize programmatically in my viewDidLoad method and Interface builder is still giving me errors. All other tutorials I've seen have only talked about one-way scrolling with UIScrollView, so here I am. Here's some screenshots of my storyboard hierarchy as well to make things more clear:
Hierarchy
Errors
Does anyone have any experience/workarounds for this kind of problem?
Interface builder is TRYING to be helpful and make sure that you don't have arbitrary constraints on your content view.
Remember that Interface Builder just cares about the initial state of the views it loads. It does not care what you do with them after they have been loaded.
Make IB happy by giving it some rational initial size for your content view. Then programatically after your scroll view loads you can resize the content view and set the scroll view's content size programmatically.

Adding a UIScrollView to an existing view with lots of objects... how to easily make whole view scrollable?

I made an app that has a lot of content on its view (images, buttons, text labels, etc.) and is optimized for the iPhone 5 display. However, the part of the view that is missing when viewed on an iPhone 4 screen is just additional settings, and is perfectly acceptable to be hidden until scrolled to.
So, how do I made my entire view scrollable for iPhone 4 users? I tried just dragging and dropping a UIScrollVIew object over the top of the whole view, but it doesn't add scrolling capability.
I have worked with UIScrollView before, but it was always something I added to the view before anything else, and don't know how to go about adding it to my view now that there are already bunches of objects. Hopefully there is some easy solution that doesn't require manually addig every object as a subView, etc.
Thanks for the suggestions!
I don't know how your views are created, but the easiest thing would be to change the class of the main view from UIView to UIScrollView.
From the InterfaceBuilder you can select all your content views (images, buttons, text labels, etc.) and then select Editor > Embed in > ScrollView.
This will create a UIScrollView containing al the views selected.
WARNING: you will lose all constraints between these subviews and the superview or the layout margin. Relative constraints (from subview to subview) will remain.
This approach is very useful when you wan to make only some content scrollable.

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