iOS - reversed height/width with orientation - iphone

I'm creating a custom container view controller but when I want to resize the frame of one of the child viewcontroller's view its size is not good regarding the orientation of the screen.
To be more precise in the init method of my container I retain 2 instance variable (2 viewcontrollers). Then in the viewdidload method of my container, I want to resize the frame of the view of one viewcontroller and add the 2 as subviews.
My problem is that I'm working in landscape orientation only and when I ask the frame size of one of the viewcontrollers, the height and the width are reversed. I should have a width of 1024 and a height of 748 but I get a width of 748 and a height of 1024 !
Do you know why ?
PS : in all the viewcontrollers including the container viewcontroller I set the shouldautorotate method to UIOrientationInterfaceIsLandscape()
Thanks a lot

I'm not sure of your exact setup, but here's some general info that may help:
When you have view controllers very near the top of the view hierarchy (or indeed at the top) you can find that you get this 'swapping' effect of the width and height. The swapping usually manifests itself on the frame, but not on the bounds of the view. This is because bounds is effectively some transformations applied to the frame -- and sometimes these transformations include a 90 degree rotation (due to device being in landscape mode).
Note that the exact timing of when you check the frame property can be important too. If you're checking the property after the view loaded but before it has appeared on-screen, you can get the 'wrong' result.

Related

How to use UIScrollView in IB? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
steps for creating UIScrollView with Interface Builder
I am using UIScrollView for one of my view. I have added view first and then scroll view, then some controls over scroll view, all are added through IB. Every things works fine until the page is fit, some controls need to be added down that is exceeding the UIView length, I am not sure, how to add controls in IB in that case, So I have added programmatically, but my scrollview is not scrolling down, it is scrolling upto my view height, I have tried setting the new view height, scrollview's frame and content size nothing works, Can anyone please suggest me what to do now...
i) how to add control in IB more than its view length.(view height are disabled).
ii) How to make my scrollview which covers full view.
Create the view for the UIScrollView separately.
Technically, UIScrollView can hold controls directly in it. But that is not the point of it. You should always (if using IB) design the view separately and then place it inside the UIScrollView and set the contentSize property to the size of that view.
So, instead of putting contents directly in the UIScrollView in the main view, drag a separate view from the IB objects library on the nib (not on the main view).
Set the width of this view to the width of UIScrollView. Start placing controls on it and extend the height of view. For every new control to be placed, the height must be increased so as to hold that control. You should not place control outside a view from IB. (Although you can).
After designing the view, drag the view inside the UIScrollView and set the Y value of this view to 0. (When you drag a view inside UIScrollView it seems to upset it's Y value).
Now programmatically set the contentSize of UIScrollView to the size of this view. For this you'll need to create an IBOutlet for the UIView you just created.
myscrollview.contentSize = myview.frame.size;
And you're done.
-EDIT-
it is so simple. Follow the steps I'm giving you below you will get what you want.
decide the actual size that is the size in which you want your scroll view to display. say it is 100 * 5o.
set your UIView size also 100 * 50.
Now increase the scrollview hieght in nib.
add what you want
Now check upto what size you have reached.
Suppose it is reached upto 300
So set your contentsize 100 * 300 or 100 * 310 programmatically
In nib set scrollview size 100 * 50
Enjoy programming.
It's very simple, first remember your UIScrollView Frame and then just change UIScrollView frame's Y-position by subtracting 100 (e.g 0 to -100) and add same to height(460 to 560). Then simply add you controls at your required position by continuing this steps...
For eg:
ScrollView Frame (0,0,320,460)
after CHANGE:
(0,-100,320,560)
After finishing with controls adding simply set previous frame like:
(0,0,320,460)

Scaling a sub classed UIView

I have created a subclass of UIView and am trying to scale and move the view from within its m file but am running into some problems. When I used the command:
self.frame = CGRectMake(self.frame.origin.x-10,self.frame.origin.y-10,self.frame.size.width/2,self.frame.size.height/2); the object moves location but does not resize (the view only contains a few UIImageViews). In the xib file of the sub class I have the options checked to Clip Subviews and to Autoresize Subviews but neither appears to happen. Any ideas as to why the view will not resize with this command and how I could get it to resize.
Resizing your view is not the same as scaling it. Think of your view as a picture frame. What you're doing above is moving the frame, and also moving the lower right corner (you're shortening the frame's wood bars) - but that does not automatically shrink the picture.
There are four ways of resizing a view with subviews:
Let the superview clips its subviews (by setting view.clipsToBounds = YES): Subviews do not resize or relayout, but only show in the area that is inside the frame.
Let the superview not clip its subviews (by setting view.clipsToBounds = NO): Changing superview size does not have any visual effect on subviews, they also show outside of the frame.
Give the subviews autoresizingMasks: The subviews do not change size, but they relayout according to their autoresizing mask (for instance, a subview may always stay 10 px off the lower right corner of the frame, or may always span exactly the width of the frame.) Note that this does not necessarily automatically scale subview content. Set subview.contentMode accordingly.
Scale the superview: By setting superview.transform = CGAffineTransformScale(superview.transform, 0.5, 0.5), you shrink the superview and all its subviews (you essentially zoom out). Note that this makes superview.frame undefined, which means you shouldn't use that anymore. It can also make things a bit blurry.
You could also "manually" change all the subviews, but that kind of defeats the purpose of having a nice view hierarchy.
As MishieMoo said, temporarily set the backgroundColor of your superview to something visible. This will very likely show you that your view is indeed changing.

UIScrollView auto-scrolls to top after SetContentSize during orientation change - how can I prevent that?

I have a UIScrollView in which vertical only scrolling is enabled. I'm displaying a grid of buttons (similar to the photo viewer image grid). The grid has to be drawn differently based on screen orientation, so that all of the screen real estate is used. Given the size of my buttons, I can fit 3 per row in portrait, and 4 per row in landscape.
I reposition all of the buttons in: willRotateToInterfaceOrientation:duration and then call: setContentSize: on my UIScrollView. Everything seems to work just fine, with the exception of the auto-scrolling that occurs after the call to SetContentSize:. In other words, let's say I was in portrait, and scrolled 3/4 of the way down the list, when I rotate to landscape, it auto-scrolls all the back up to the top.
The interesting thing is, in the same scenario, if I were to do a small flick scroll up or down, and then immediately rotate the device, the scroll view redraws correctly, and retains the current scroll position!
So, to be clear, the culprit here seems to be SetContentSize:, but obviously I have to call that for the scroll view to scroll correctly.
Any ideas on how I can retain the current scroll position?
Thanks!
You might try implementing the UIScrollViewDelegate method scrollViewShouldScrollToTop:, which tells the caller whether to scroll to the top or not. You may have to have some flag in your delegate that indicates if a rotation is underway or not, because under normal conditions you may actually want the ability to tap the status bar and have the scroll view scroll to the top.
If, on the other hand, you don't ever want the scroll view to scroll to the top automaticlly, simply implement that delegate method and have it return NO.
I had this problem, just did this and it works well for me
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//calculate percentage down scrollview currently at
float c = self.scrollView.contentOffset.y / self.scrollView.contentSize.height;
//reposition subviews in the scrollview
[self positionThumbnails:toInterfaceOrientation];
//set the new scrollview offset to the same percentage,
// using the new scrollview height to calculate
self.scrollView.contentOffset =
CGPointMake(0, c * self.scrollView.contentSize.height);
}
In my case, I have a scrollview with a fixed width to device size, and variable height

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.

How to auto-resize UIView proportionally?

I have a UIView whose height should always be exactly 1.5 times the width. When the view is auto-resized (in this case, because the iPhone is rotated), this proportion gets messed up. How can I make sure the height/width ratio doesn't change as the view resizes?
You need to set the views autoresizingMask property to UIViewAutoresizingNone. This will prevent the size of the view from changing at all when the parent view's size changes (such as when the phone rotates.) If you want the view to resize on rotation, but maintain it's aspect ratio (for example if you want it wider in landscape but still 1:1.5), then you will need to set the view's frame yourself to the desired dimensions (but maintaining the desired ratio) in the view controller's willRotateToInterfaceOrientation:duration: method.
You could implement the -sizeThatFits: method for your view to keep the size in proportion.
Alternatively, you could use a custom superview that implements - (void)layoutSubviews to have complete control over the layout.