Prevent resize of UIViewController when changing orientation - ios

The Maps app has a "custom" behaviour and doesn't resize the bottom menu when in landscape orientation.
What's the best way to achieve the same effect, short of resizing the view manually on every orientation change?
See attached images to get a better understanding.

This is done using size classes.
The easiest way to do it is to use the size classes right from your storyboard.
Right next to constraints and size related options from the size inspector you have this little + sign.
Hit it to define a different behavior for each size class.
See here for more, including how to use size classes from your code.

Related

Different iOS devices size programming approach

I am starting a new project which should be working on every iOS device size possible.
The project is rather simple. The main view will be a scroll view and it will hold a '+' button (where it says 'button' in the image) in the top right corner. (It does not really matter, I'm just trying to give the general idea of what I'm trying to understand and implement.)
A small example:
What is the right approach for this kind of problem?
Should I create a different storyboard for each device?
Should I start creating an adjustable scroll view that will hold the needed buttons with some constraints (if at all possible)?
I have read this tutorial:
auto layout
which explains the auto layout nicely, but does not mention the issue I'm trying to figure out.
Any thoughts?
Use AutoLayout and position your views relative to one another (so no x pixels spacing between views). Make only one storyboard for all devices, when a different view should be loaded on another device (like a completely different layout), select the appropriate size class and adapt the views and constraints.
Then it will be recalculated on every device.
The storyboard has a preview section where you can choose a device to simulate the view on.

interface builder : make the view the same size as the iphone, to know exactly what constraints to add?

is there a way to have the view from interface builder in Xcode, be the same size as the iphone we use to test the app? The size of the viewcontroller seems to be 600*600. So when I move a UILabel somewhere to the left for example, it will be placed as if it was on the right on my iphone. Which is not easy to set the right constraints.
Do you have some tips to manipulate the items and place them easily? For now, I just align the item with the center point, and move it little by little.
The reason this happens is because of Apple's emphasis of size classes. It looks like a rectangle because whenever you are adding constraints and views, they'll be applied to every size class (i.e. horizontal/compact, vertical/compact, etc).
In english, it means it's applying those changes to run as such on any device.
To create constraints and views for just one size, you'll want to edit the size class you are working with. At the bottom of Xcode where it says "wAny hAny", click that and you can set what device you want to work with:
The whole idea of this is adaptive design, and I've got a post explaining it in more detail here.
The thing is that there is no one correct size for the iphone screen because there are so many different screen sizes. You can set the view size to anything you want in interface builder by clicking on the view and going to simulated metrics -> size but what you really want is autolayout so that your views fit properly on every device.

Finer grained UIView rotation in a UIViewController

I have a UIViewController that overlays controls on a view presenting what the camera sees. I have a couple of scenarios I would like to allow.
For the iPad, I want to keep the controls on the right most edge of the device, by your right thumb, no matter what the device's rotation. The controls should rotate their content so that their top is always upwards (away from the ground). I don't want the camera view to rotate at all, because that would just be silly – its position & size should stay the same and its contents shouldn't rotate either.
For the iPhones, I want to keep the controls at the bottom of the device's screen, by to the home button, wherever the home button actually is. The controls should rotate their content so that up is always pointing upwards. Again, I don't want the camera view's frame or content to take part in any view rotation animation at all.
I'm using auto-layout.
I'm wondering if there is any way to describe some or all of this in a storyboard. In particular, it'd be great to be able to describe that some view positions need to autorotate (ie, the controls, on iPad), but that other views don't (the camera view).
A question from 2011 indicates this wasn't possible at the time, but perhaps things have moved on since then? If it's not directly supported, can you suggest an approach and are there some sensible places to be hooking in to autorotation to achieve this?
Ok, this isn't quite a complete answer, but I tried a few things which look promising.
First, you can create a separate set of constraints for portrait vs. landscape using the size specifiers: landscape is w Regular, h Any; portrait is w Any, h Regular (I think -- double-check these) This is accessible via the pop-up control in the bottom-center of the storyboard view. By installing different constraints for portrait and landscape, it should be possible to scale the width and height of your controls' container view so it appears to be in a constant position w.r.t. device orientation; in other words, the container doesn't actually counter-rotate -- it scales so it effectively looks like it has counter-rotated.
I got this close to working. It looks like it's doing the correct thing in the storyboard view, but when I actually run it, I get debug messages about conflicting constraints. Not sure how to fix this, but maybe play with the constraint priorities? That sometimes helps.
A second thing I (partially) tried was creating a custom container view class which counter-rotates itself to the correct position based on the device orientation (in the UIDevice class). You implement this by overriding layoutSubviews. For each orientation, you define a transform which puts it in the correct position, and set the view's transform property.
Another possible solution is to override updateConstraints in your view controller and add/remove constraints to position/scale your container to the correct place for each orientation.
For all of these, the idea is that you "force" the container to be in the correct place, but leave the subviews (the actual controls) alone. The controls should do the right thing if their constraints are independent of the specific orientation of the container view.
So, those are some ideas anyway... if they lead you to an actual solution, could you post it? I anticipate having a need for this myself.

How to stretch UITextViews in UIScrollView to fit horizontal size after rotation?

So I have a long form with 11 UITextViews. It's just long enough exceed the iPhone older 3.2" screen so I had to throw it all in a UIScrollView. Now when I rotate to horizontal the UITextViews won't resize to fit the newly available space to the left.
Any ideas about how I can get around this?
First, do you mean UITextFields? (instead of TextViews)
There are many different ways to go about this.
First of, did you use Interface Builder to build the view?
If the view is simple, you can try the elastic positioning provided by Interface Builder, you might have to fiddle with different options.
Another way is to use Autolayout system, available in iOS 6.0+
Or, if you're comfortable with handling frames yourself with codes, you can have different frame sizes set for when the view has rotated.
Or, you can create a separate xib file just for the landscape view and have the program load that xib when the phone rotated.
All of the above are widely used methods for handling rotations, you should choose what fits best in your situation.

How can I use storyboard iOS to layout both the portrait and landscape orientations of a single view?

I want to minimize the amount of code I have to write, and use storyboards in xcode to specify the way the view should appear when in both portrait and landscape views.
What is the best/recommended way to do this that minimizes code? I've done some research, but am having trouble finding a simple solution..is it necessary to do some conditional segues, and re-hook up everything in my landscape view, or is there a simpler solution? Thanks!
Generally you define the autoResizingMask (or go to the size inspector in Interface Builder, as shown below) so that the controls will move or resize as the screen size changes. If you do that, you'll generally have pretty decent support for both landscape and portrait. You'll only have to do programmatic changes to the controls' frames if you do some fairly significant changes on orientation changes (e.g. you want to shuffle the various controls around so that they are in very different positions with respect to each other when you change orientation or you want to load very different UIImages). But 90% of the time, autoresizing settings can handle simple moving/resizing/recentering of controls for you:

Resources