I'm building an app that uses a UIView that contains a UIScrollView within it so that when the keyboard shows up, users can still scroll downwards to see the content within the view. It seems like I have gotten everything perfectly set up but when I rotate, everything goes completely unusable. The views are all out of place and I am unsure what's the strategy to handle this. I have the views autoresizing but they don't seem to be doing it correctly.
Should I manually check to see if the rotations have occurred and reset the frame without autoresizing or is there a way that I can accomplish this with auto resizing?
The situation is this:
Portrait mode - form fits fine. When keyboard shows up, scroll view is resized but form does not.
Landscape mode - form doesn't fit fine and when keyboard shows up, scroll view is messed up.
Do I need to resize the form view when rotated to landscape mode?
Thanks!
You can reposition things back to original by using:
-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
//reposition code
}
I have an issue where I want the keyboard to resign upon the ipad rotating.
If the keyboard is open in portrait, and I rotate to landscape, the keyboard appears in landscape.
HOW DO I RESIGN the keyboard when I rotate!
TY
Related
I've got a button designed on Portrait Orientattion, when I switch to Landscape it doesn't appear, what should I do so that it stays all the time?
Make sure you set the proper AutoresizingMasks for your UIViews. For example, it might be that your button has a y-coordinate that is larger than the device's width and has a fixed top resizing mask, so if you turn the device to landscape mode it gets clipped. Doing this...
button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
...will cause the button to shrink its top margin, moving on screen.
In your comment you mentioned that this is a split-view app, if your button is in the root view controller of the split view, you should probably add support for restoring the root view controller as a popover.
I have a controller that manages a UITextView. Normally, in an app that supports multiple interface orientations, I would simply override -shouldAutorotateToInterfaceOrientation:, set the appropriate auto-resizing masks, and go along my merry way. While going along my merry way, if I were to begin editing this UITextField in, say, portrait mode, then rotate the device to a landscape orientation, the keyboard would animate nicely to landscape mode along with the rest of the view. This is what I want.
Now, in this particular app, I have a root view that must only ever be in portrait mode. This is a camera preview view. I also have an overlay-view for the camera-view that I would like to have support all interface orientations. This is where the UITextView is located.
So, as a result of the fixed-orientation root view, I cannot use built in rotation: I have to do this manually. This isn't a problem, I can register for the UIDeviceOrientationDidChangeNotification and manually animate the appropriate rotation and frame adjustment for the overlay view.
That's good enough to get the view positioned correctly, but the keyboard would still only ever show in portrait orientation. Again, I can correct this with UIApplication's -setStatusBarOrientation: every time I get a notification that the device has rotated.
But that's where the problem arises. I would hope that the combination of:
Register for rotation notifications
Manually rotate view
Set status bar orientation (with animation)
would be enough to exactly replicate the automatic rotation behavior. But it falls short in one important way: If the keyboard were to be shown in one orientation, then rotated to another, the keyboard would remain defiantly in the original position, as if -setStatusBarOrientation: were never called. As far as I know, the only thing that affects the keyboard's presentation is the application's status bar orientation, and there is only the one method for setting it. So am I out of luck? Is it really impossible to make the keyboard rotate with a view manually like it does with auto-rotation?
Addendum
In an effort to avoid covering old ground, I've tried the following solutions hacks:
Upon orientation change, resign and immediately become first responder again. This does make the keyboard move to the appropriate orientation, but it does so without animation, and occasionally does really bad things like show a landscape-sized keyboard in portrait and vice-versa.
Upon orientation change just resign first responder. This also has the odd behavior of instantly moving (but not resizing) the keyboard to the new orientation, then dismissing it with animation. It's very ugly and jarring.
One of our apps does this (because we didn't say "no!" loudly enough when presented with the original design) using crazy "orientation stack" code. I remember fixing this problem by disabling orientation when the keyboard is up (ickyyyy).
Instead, consider supporting rotation by "counter-rotating" the camera preview view instead of forcing the VC to portrait-only. If this looks a bit odd, you can do the "nasty hack" version: Add the camera preview view as a subview of the window, under your VC's view, and give your VC's view a transparent background.
Maybe late to the party. I stumbled upon the same problem. Trying to fix it in iOS 6.
Apparently Apple didn't recognize this problem in the meanwhile, otherwise they would've fixed it by now: have the -setStatusBarOrientation: method include other interface elements besides only the status bar as well, or have alternative methods to set the orientation of the keyboard and other elements. A pity they didn't
Disabling orientation rotation when the keyboard is up, is no solution for me, but I found another simple solution hack:
return NO in -(BOOL)shouldAutorotate
return UIInterfaceOrientationMaskAll in -(NSUInteger)supportedInterfaceOrientations
listen for device rotation notifications
Then when you receive such notification:
hide the status bar
when the keyboard is up, dismiss the keyboard ([myTextField resignFirstResponder])
perform manual rotation animation
set the orientation of the statusbar ([sharedApplication setStatusBarOrientation:newOrientation animated:NO])
show the status bar
if the keyboard was visible before, present it again ([myTextField becomeFirstResponder])
The effect is that the status bar and the keyboard gently slide out before the manual rotation animation and gracefully slide back in, when the animation is done.
BTW, I also found this interesting article by Corey Floyd: http://coreyfloyd.tumblr.com/post/8212203583/2-ways-to-rotate
Although his second method: Tricking UIKit, only caused more confusion with me.
I have a landscape view that has a datePicker control on it, which was designed using IB. The datePicker control loads correctly the first time the view is loaded. If I dismiss the view and then load the datePicker view again, without rotating the app back to portrait first, the control resizes. If I load the datePicker, dismiss it, rotate the phone to portrait, then call the datePicker again it works fine. Is there a way to trick the app into thinking it was rotated back to portrait without actually rotating it? Is there any other reasonable way to deal with this?
If you dont want to rotate it on orientation, you can transform it manually. Hope I understood correctly what you were trying to explain.
This is a pretty weird error. I have a tab bar controller, with a nested navigation controller, which then has your standard tableview. When you click on a cell a new view is pushed onto the controller. This is a regular view with a nested uiwebview, that takes the entire view up.
When entering that view in portrait mode it looks great, when you rotate it to landscape it looks great, and back to portrait again is good.
But when you enter that view using landscape it looks great but rotating to portrait doesn't seem to resize, the width is still too wide and the text is larger.
I've tried
1.webView.frame = self.view.frame;-That didnt seem to change its behavior
2.Both the view and the webview are set to autosize and like i said it works when starting in portrait
3.[webView setFrame:CGRectMake(0, 0, 320,411)]; when rotating to portrait from landscape. This is really weird, it makes the webview consume half the screen. Font is still large.
4.I've changed the autoresize to disabled, manually resize them on orientation change and then do a [webView reload];
Ive tried various other things and combinations of things. This problem is consistent across all of my subviews that are webviews.
I am sort of new so please be as specific as you can.
Use <meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;'> in the head of your html
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.