How to handle different views for different device orientations? - ios

I have a subview in portrait orientation (storyboard scene):
that I want to move and resize like this when the device rotates to landscape orientation:
What the best (or easiest) way to handle this should be?
I'm thinking about the following options:
Creating different separated xib files (one for portrait and another for landscape), and loading the corresponding one?
Rotating + translating + resizing the subview when orientation changes?
Directly creating both subviews (horizontal-bottom one, and vertical-left one) and hidding the corresponding according to the orientation?
I need help with this scenario, I donĀ“t find a solution that works for me. Also if I'm missing any other option, I'll appreciate to know.
Thanks in advance
EDIT: This is an app targeting iOS 7 and above. I'm not using the size classes feature, just autolayout.
EDIT 2:
Setting a new frame to the subview.
What should be the difference of this option with option 2?

Option (2) would be your best bet. Store two sets of constraints and install / uninstall them depending on the orientation.
If you were using size classes, you could do this completely in IB.
(1) is overkill, and (3) is unnecessary.
In portrait mode you have the following constraints for your subview:
Horizontal space constraints for the left, right sides
A vertical space constraint for the bottom side
A height constraint
After the device is rotated to the landscape orientation, you'll change the constraints so that you'll end up with the following constraints for your subview:
Vertical space constraints for the top and bottom sides
A horizontal space constraint for the left side
A width constraint

Related

iOS Storyboard Constraints/Traits for portrait and landscape view

my iOS project consists at the moment of one single UIView or UIViewController. The controller class is called MainViewController.swift.
The view of the view controller has a subview which I've placed at the bottom:
I've set the auto layout option to keep the distance of the subview for every device size the same:
Now I want to keep the sub view always on the short side of the parent view, which means that in landscape mode the sub view show be on the right side of the parent view:
I've checked some tutorials and other posts in the meanwhile:
Ray Wenderlich Tutorial
Stackoverflow Post
At this point it is not clear to my how to realize such a behavior best?
Possibilites I've found to solve the issue:
Vary for traits...but how?
Constraints?
Programmatically - I think this would be the fastest solution, but I really want to use storyboards and learn the correct usage.
Here you can play with size classes and traits. if you want give constraint in portrait mode you have to select compact width and regular height and for landscape compact width compact height.
Please go through following steps to constraint portrait and landscape separately.
1) Please select mode either landscape and portrait from traits.
2) Now, you can constraint each mode one by one. suppose i am giving constraint to red view in portrait mode and i will enable particular constraints for for portrait size class so it will be disable for landscape mode.
3)once we are finished with portrait mode i have switched to compact height compact regular size class which is landscape mode.
4) Now, we can constraint the landscape mode as shown in above screenshot.
As we can see constraints which is light in color are disable for current size class.
So this is how we can constraints landscape and portrait mode separately.
Because there is no size class or trait difference between an iPad in landscape, and an iPad in portrait, you will ultimately have to handle at least some cases programatically. That being the case, you might as well just handle all cases programatically with a method that does something like:
Get current screen size
If width > height, add constraints to center the subview vertical and pin it to the right edge. Otherwise, add constraints to center the subview horizontally and pin it to the bottom edge.

How to set autolayout constraints properly?

My GUI looks like that:
Image
I don't really know how to set the constraints of the image view in the middle properly.
It works in portrait mode if I set constants but if I rotate the device it doesn't work anymore because the constant value is wrong for landscape.
Do you know how to solve that?
When you see a red-lined constraints that means the there is at least one missing constraint. When adding constraints to a component it should cover the whole frame of it (size: height/width and origin: x/y). If you want to let the height/width of the imageView dynamic (based on screen size), then you should add Equal Widths and Equal Heights constraints between the imageView and view container.
Also, in xcode 8, you can easily choose the desired size class, by choosing the device and its orientation. So, let's assume that you want to setup the constraints for all the iPads in landscape mode, in storyboard you should pick -for example-:
Also, you might want to check this video from WWDC 2016.
Hope this helped.

iOS - Autolayout - Increase/Decrease view size proportionally on orientation change

I went through ray wenderlich's tutorial about autolayouts (link) and then began working on a demo project thinking I've figured it all out but I was wrong. As shown in the screenshot below I have a navigation bar, 2 views and 1 button. The layout on portrait mode looks fine without adding any constraints on views or the button, and understandably in landscape mode views are messed up. I tried adding following constraints on views and those don't seems to work.
View#2: Select view 2 > Editor > Align > Horizontal center in container (hides view completely)
Add Top space to superview. Again view goes away from both landscape and portrait preview.
If I can display view#2 correctly I am planning to add vertical space between view#2 & view#3 and then between view#3 and button#4.
My main concern is to resize the views so that it shows all views and buttons in iPhone 4s landscape mode. Any advise or suggestions are appreciated.
EDIT: Here's the end result that I am trying to get:
The reason your views go away when you add constraints is because a UIView has no intrinsic content size, so its size is {0,0}. The view appeared when you didn't add constraints because the system adds constraints for you, if you don't add them yourself; the system added ones are top, left, width, and height. So, you need to set the size of the views somehow. You can give them explicit size constraints, you can pin them to the edges of the superview, you can give them relative heights based on other views, etc.
Since you want the 2 views to get proportionally smaller in landscape, you should give them heights that are relative to the superview. You do this by selecting the view and the superview, and choosing "Equal Heights" from the pin menu. Edit that constraint to change the multiplier to something like 0.25 for the blue view and 0.2 for the orange one (this assumes that orange or blue view are the first item in the constraint -- if they are the second, then you should use the inverse values of 4 and 5). You should also do the same for the widths, since it seems you want them to get proportionally smaller too.

How to Manage Complicated Views Hierarchy using Auto-layout in iOS Sdk

I am working on an iOS application and it will be compatible for all devices iPhone 3.5, 4, 4.7, 5.5 inches and iPad also.
I am designing a screen it has 5 subviews, as i view this screen in different screen it does not resize properly.
I am using Auto-layout to manage that screen and I have set the every possible constraint to manage this screen.I have to manage the Subviews height and width as the devices changes.
Following are the steps taken care by me
1)Set the Equal Height Constraint for all subviews
2)Equal Width Constraint for TopView1 and TopView2 set the High priority and set the proper Horizontal spacing, Leading, trailing edges for these two top spaces accordingly.
3)Equal Width Constraint for MiddleView1 , MiddleView2 and MiddleView3 and set the High priority and set the proper Horizontal spacing for these two and vertical spaces from TOpViews accordingly.
4)Set the Width Constraint for bottomView and set the High priority and set the proper Horizontal spacing for these two and vertical spaces from MiddleViews and bottom spaces accordingly.
Prior to this i have not used auto-layout in such complicated way.
Following are the screen shotes depict my problem.
EDIT:
#Ash Furrow please see attached a screen shotes with constraints.
I am laying out the base screen on Any Width Any Height
Please anybody suggest me how should i manage this view
Hmm. Looking at what you've done and the feedback to your question, everything seems correct.
I think I see the problem. The issue doesn't appear to be with your storyboard (here in case anyone is interested), but rather the use of Xcode. Instead of changing the view controller's simulated "Size" metric, use the Assistant Editor to view a preview of whatever device you want. I've tried that, and ran the code, and in both cases they appear to work.
So to recap, use the Preview in the Assistant Editor instead of changing the view controller's properties to resize a view hierarchy.

Xcode IB Storyboards orientation and container views

In an IOS 6 iPad app, I have a container view controller with multiple container views. Currently I have locked my app to landscape and works fine but I'd like to support portrait as well. Everything is set up using auto layout and constraints via Interface builder. If possible I'd like to keep one storyboard for consistency, maintainability etc.
The layout is this: Header, Left-side menu, two content panes (side by side in landscape) and a foot pane, I have all panes resizing except the content. When rotating from landscape to portrait I'd like one content pane to slide below the other (currently it blows off the screen), and both to stick to the edges of the container view.
In HTML5/CSS3 this would be easy to do but I'm stuck in IB, any help/ideas would be great!
Thanks!
EDIT:
Solution -
Following #Charles A.'s suggestion, I linked the NSLayoutConstraints to IBOutlets and manipulated spacing/priority in code. Where I really struggled was using Height and Width constraints. If you moved anything, Interface Builder would delete or override these with Leading/trailing & Top/Bottom constraints. I finally gave in and got rid off all height & width constraints, and used only leading/trailing/top/bottom.
2 things I figured out: Constraints have milestones(one at priority #750 for instance) so if you pragmatically change priority from 749 to 750, you will get:
Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported.
But if you changed from 750 to 800 you are fine.
Also, after manipulating constraints, I needed to call:
[self updateViewConstraints]
I had found a post that suggested [parent updateViewConstraints], which didn't work, the one above did!
Anyway, I hope this helps others in this spot since there's not much out there.
It's hard to answer the question specifically without knowing how your layout constraints are setup to handle your two content views. Having said that, I would probably go about this UI by having my layout constrained similar to this (I'll use the visual format to describe, I'm assuming that the superview is the parent of the two content views in this case):
|-[contentViewOne]-0-[contentViewTwo(==contentViewOne)]-|
If the constraints are setup as above in the storyboard, you could create an IBOutlet of type NSLayoutConstraint* and connect it to the horizontal space constraint between the two content views (the one that specifies a constant value of 0, in my case above). When you animate from landscape to portrait, just set it's constant value to the negative width of contentViewOne. This should have the desired affect. You'll obviously also have to set it back to 0 when rotating from portrait to landscape.
It's worth noting that I assume your content views are equal width. If they're not you would potentially also need to make an outlet for a width constraint on the one sliding under in order to temporarily set it to the same width as the one covering it.
There are many potential ways to address this layout using autolayout. What I've described above is just one such way. It comes down to what makes sense given the layout you already have.

Resources