When do autoresizing masks take effect in iOS? - iphone

I have a nib that I originally created for an iPhone app with dimensions 320x480 and with autoresizing masks set up to expand the view in every direction should its superview be large.
I am now making my app universal, and am using the same nib and showing it in a page sheet on the iPad.
My problem is that I make some calculations based on the frame size, which is still showing 320x480. But in other methods, the frame size is showing correctly as the size of the page sheet.
Question: When do the autoresizing masks take effect so I can make my calculations at the correct time?

The autoresizingMask property takes effect when the frame of it's superview changes. The superview property resizesSubviews must be YES. When you load your NIB, the superview's frame is set as in the NIB. You can set this to whatever you want while initializing.

It has been a long time since I've done something with development for the iOS, but I remember it mattered when rotating views when the device's rotation changes. So when you setup a view controller that will enable all device orientations, it will set the frame of it's view. That view will at his turn set all the subviews' frames. It'll look at the autoresizing mask to check how it has to alter the frame.
I'm not sure about this, but I thought it was something like this. Test it and let us know!
ief2

Related

Rotating UIView and background to landscape mode

The initial root view controller is 9 (3x3) buttons with a custom background in portrait mode. When the device is rotated into landscape mode the last row of buttons (of course) are cut off and the background (which is 320x480) doesn't fill the width of the screen.
What is the proper way of handling this? Do I need to move and resize the buttons myself? Do I have multiple Nibs? How do I resize/rotate the background?
Use shouldAutorotateToInterfaceOrientation and/or deviceDidRotateSelector in your viewController to reposition / layout & scale your views programmatically as you require.
If you set the auto-resizing masks on the buttons to have flexible margins in all directions they should reposition themselves appropriately when you rotate the device. You can do this either in code, or in Interface Builder (which has a nice little simulator demonstrating the effect)
With regards the background, what I prefer to do is to make the image the combination of the maximum proportions of each orientation, and then center it. For instance, make your image 480 x 480, make the view that houses it the same size and then use the appropriate auto-resizing masks to achieve the desired effect.

How to determine the frame of a view after an iPhone is rotated, before the rotation actually takes place

I'm currently dealing with an iphone view controller which contains a paging UIScrollView, to display multiple pages of information. My application needs to support a landscape mode, and I've been having a bit of trouble figuring out the right way to implement this.
In order to maintain view continuity, I want to resize my views manually in two steps. First, I override willRotateToInterfaceOrientation. In this method I extend the width of all my views in the paging scroll view to the width that they'll end up at in landscape mode. Then, in didRotateToInterfaceOrientation, I reduce the height of the views to fit the height of the landscape mode.
My question is, how do I determine the new width and height to resize my views? Hardcoding the exact values feels like a bad hack, and I get the sense that there must be an elegant way of solving the problem.
I'm not sure why you're doing layout in didRotateToInterfaceOrientation:, which happens at the end of the rotation. In any case, the new frame should already be set by UIViewController.
If you're going to sync things to the animation, look at willAnimateRotationToInterfaceOrientation:duration:. According to the docs,
This method is called from within the animation block that is used to rotate the view. You can override this method and use it to configure additional animations that should occur during the view rotation. For example, you could use it to adjust the zoom level of your content, change the scroller position, or modify other animatable properties of your view.
By the time this method is called, the interfaceOrientation property is already set to the new orientation. Thus, you can perform any additional layout required by your views in this method.

trouble with rotating view (and resizing elements within) in ipad application

I'm having a nightmare with the rotation on iPad. I've searched all over the place for some tutorials, but nothing seems to really be for what I want. (Possibly not searching for the right thing?!)
I have a portrait view by default which is an image and a button inside the view. When I rotate, I detect this can work out if it's landscape. I then try to set the frame size of the uiview to fit nicely on the screen.
If I let it autoresize, it simply stretches and fills the screen. This I don't want.
but the trouble is, when I resize, the button gets resized too, but not in the same ratio as the image.
My question is: What's the best way to resize the view. I wanted to simply reduce the uiview by say 60% and it resizes EVERYTHING in that view with the same 60%. The only way I see this is working at the moment is to create two views... but that's twice the work and maintenance!
I've tried messing with the autosizing arrows in Interface builder, but that again seems to screw things up more!
I'm completely lost here!! Thanks for any info
The problem you have there is that the view is automatically resized to the screen ratio. On an iPad in Portrait Orientation the screen size is 1024x768. After the rotation to Landscape the origin rotates too and your screen content is skewed or stretched to 768x1024.
What you need to do is to override the
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
message of the UIViewController of the view which rotates. This message is called within the animation block of the rotation. You just set the framesize of your subviews (the button) to whatever is best for you. Once i had a problem with rotating an OpenGL view. The content of the view was stretched when rotating to landscape. Since it is not possible to alter any OpenGL matrices within the animation block the only solution i found was to make the view quadratic and to set the origin behind the bounds of the screen (in -x direction). You have to override the message also to reset the origin above the screen (in -y direction) bounds in landscape mode, to keep the viewport in the middle of the screen. That way the view kept its ratio. Whatever solution is best for you, overriding this message should work out.
Have you tried disabling the autoresizesSubviews property on your UIView? It should prevent any size changes on the subviews when you resize your view.

Problem with autoresizing when iPhone is rotated

In my iPhone app, I have a view (let's call it RectangleView) within the content view that I'd like to scale, along with all its subviews, when the iPhone is rotated. So, when the phone is rotated from landscape to portrait mode, I'd like RectangleView (and all its subviews) to keep their original shape and position relative to each other, but just get smaller. I am using autoresizing on it and all its subviews in Interface Builder to try and do this.
Now here's the problem. When the phone is rotated, all of RectangleView's subviews scale and move relative to the entire content view, not relative their parent view (which is RectangleView). This is a problem because the content view is now a different shape (portrait) than it was before (landscape), and so all the elements on the screen are in the wrong places, when they should just be scaled down within RectangleView. And I am confused because some of these elements even move out of RectangleView, which I didn't even know was possible since they are supposed to be contained within RectangleView.
Can anyone explain what might be happening here, and how I can just scale RectangleView and all its subviews to retain their original shape and positions, but just on a smaller scale? Thanks in advance!
Are you sure that they are moving out of the RectangleView, and it isn't that the RectangleView is resizing and filling the content area? Also, I'm not sure if it makes a difference, but I found that I needed to call [view setNeedsDisplay] after rotation to make my custom view work properly.

What's the best way to handle landscape/portrait differences in IB?

I have a view that supports landscape and portrait viewing, with the controls all moving around when you switch from one to the other. I'm currently doing this by setting the .center of each one of my controls when the user rotates the phone. The problem is that this is tedious, and requires a lot of code, and seems to defeat the purpose of using Interface Builder in the first place.
My question is: is there a way in Interface Builder for one view to support multiple looks (one for landscape one for portrait)? If not how do other people do this with IB? Do you set up 2 views?
Edit: Just to clarify my landscape and portrait views look different, I don't want a straight transform, I actually display the data differently in landscape mode
When necessary, I add UIView objects to the view in IB which I make hidden. Give it a nice background color so you can see it, and send it all the way to the background. Then use that view's frame when you need to set the frame of an object. If you have a lot of them, you might consider using UILabel instead, so you can give it a visible name in IB.
If you're worried about memory issues, just remove all these extra UIViews in ViewDidLoad and just store their frame values in member CGRects. This only works of course if you don't have any of the views auto-resize or reposition on rotate, which you probably shouldn't anyway, in this case. I do this for resizing/repositioning for any reason, not just when the screen rotates.
I'm not 100% sure if it's possible, but have you considered using different view controllers for landscape and portrait?
The AutoSize attributes of IBOutlet objects in the Size Inspector of IB (command 3) give some pretty nice options for auto-stretching and positioning of items. You can control L/R and T/B screen positions and relative width and height. You can't get full control of the layout, but most of the basic operations are there.
The only way one view can support multiple orientations in IB is to set the autosizing mask of components to either scale and/or anchor to edges. To design a totally different layout for each orientation you need to design a portrait and landscape view separately (each in its own XIB) and switch between them programatically.