I want to create a UIVIew that will not rotate when I will call to shouldAutorotateToInterfaceOrientation , and other subviews will rotate.
and i want to keep the shouldAutorotateToInterfaceOrientation suppot, and not use notification.
thanks
Be sure to define exactly what you mean by having a view "not rotate" when the device is rotated. Rotation can mean several things, depending on which coordinate system to which you refer. A better way to think about it is simply, what do you want your view to look like for each device orientation.
Just to remind, shouldAutorotateTo... is sent to your view controller by the system. You don't invoke it yourself. It doesn't cause rotation. It lets the system ask your view controller what orientations it supports.
Your VC should answer YES for all orientations it supports. A supported orientation is one where the view changes layout in response to a device orientation change, so if any layout change occurs for a given orientation, then the answer to shouldAutorotateTo is probably YES.
Altering subview layout for a given interface orientation is mostly your responsibility. Views have an autoresizingMask which is a bit vector describing some options for sizing and positioning relative to their parent, and this is often adequate. The way to fully control layout on orientation change is by implementing willAnimateRotationToInterfaceOrientation.
For example, here's a fairly permissive shouldAutorotate, enabling all but one orientation...
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
And here's how you would control how subviews layout on rotation...
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
UIView *testView = [self.view viewWithTag:16];
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
// change frames here to make the ui appear according to your spec
// including however you define "not rotating" for each view
self.subviewA.frame = .....
self.subviewB.frame = .....
} else {
self.subviewA.frame = .....
self.subviewB.frame = .....
}
}
If you want one UIView not to Rotate with orientation, one of the easy solution is to add that view to Application top Window like this. Because window dont rotate with device orientations.
[[[[UIApplication sharedApplication]windows]objectAtIndex:0]addSubview:customView];
Related
I have two different UI specs for my iOS app.
I'm facing issues in orientation change(Upsidedown not supporting) for following scenario.FYI :I'm using using self.view.frame.size.width to set width for UI and to identify orientation change i'm using UIDeviceOrientationDidChangeNotification1.Change orientation to landscape
2.change to orientation upsidedown (not settign any frame)
3.change orientation to portrait directly (setting frame for portrait mode)
On following these steps my UI frame is getting misplaced.I'm getting width as 568 for portrait mode.
Please suggest me a better way to fix this problem.
It is not good practice to change the self.view frame when rotating because its bound are handled by the UIViewController rotation logic.
You can use the willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: delegate methods for manual rotation.
you are listing to your device orientation changes and you need to allow UI rotation and listen to it with
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
//update your view's subviews
}
note that UIDeviceOrientation is different from UIInterfaceOrientation
to allow interface rotation add this to the view controller and make sure that in the project plist you are supporting the landscape and portrait in the 'Supported interface orientations' key
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
I have an iOS application and the main entry point into the storyboard is a Tabbar with with tabs. I want to support rotation but in landscape mode, each tab will look drastically different to the point I need to change the views out with others from the storyboard. At first though, I considered just switching out the entire tab bar controller when the user rotates, but I don't see how that might be accomplished. So I have two options that I can't seem to get anywhere with.
Switch each view with a segue somehow into it's landscape alternative and back. I've seen this done easily with modal views, but not with UITabbar before.
Switch out the entire tab bar somehow from the delegate so that I just have two completely separate section of my storyboard that are alike except one path is portrait and the other is landscape.
Does anyone have anything similar they are doing and could throw me a bone?
You can create a custom class for both view controllers, link them together with segoes, and then use didRotateFromInterfaceOrientation: to trigger the segues from code.
Create a class for your VC's. Add this code to the .m file:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if (fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self performSegueWithIdentifier:#"rotateToPortrait" sender:nil];
} else {
[self performSegueWithIdentifier:#"rotateToLandscape" sender:nil];
}
}
And in your storyboard, create segues between the two views. Make their identifiers "rotateToPortrait" and "rotateToLandscape", respectively. The code you added will switch the views whenever the device is rotated.
EDIT: I think I misunderstood the question. If you want to move views around, change their size, etc. when the screen is rotated, while keeping the same navigation/tab bar state, then you can do something like this in the didRotateFromInterfaceOrientation method:
if (fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
myView.frame.origin.x = aNumber;
myView.frame.size.width = anotherNumber;
// Changing the layout of the views here by resetting their origins and sizes.
// This code is called when rotated from portrait to landscape.
} else {
// Do the same thing as above, but this one handles rotation from landscape to portrait.
}
I wish to create an app that supports both Portrait and Landscape presentation.
There is no difference between the UI objects when rotating - they remain the same and function the same way in both states.
The only thing that should change is where each UI object is located on screen:
I assume that using Autolayout and Constraint won't work here since the objects actually change their location.
I wish to work in the same VC (.h and .m files), and if possible, design the screens UI in Storyboard - if it's not possible, than design one of them as a .xib file is cool as well.
The most important thing is: How to write the code that supports that?
One way, is to set the new position and dimensions on rotating your view programatically.
You can use these functions:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self yourNewPositioningFunction:[self interfaceOrientation]];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self yourNewPositioningFunction:toInterfaceOrientation];
}
What I tried so far is, in viewDidLoad, I called
self.bannerView.autoresizingMask=UIViewAutoresizingFlexibleWidth;
and
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
if (newInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || newInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.bannerView.frame=CGRectMake(0.0,
0.0,
480.0,
GAD_SIZE_320x50.height);
}
// Position the UI elements for portrait mode
else {
self.bannerView.frame=CGRectMake(0.0,
0.0,
GAD_SIZE_320x50.width,
GAD_SIZE_320x50.height);
}
}
Both of these didn't work for me.
Hmm, I don't think that AdMob's creatives can stretch to fit the size of the screen when in landscape. So despite the fact that you're stretching the frame of the view to fit, the ad itself I think will stay the same size.
This means you should still see an ad come in on orientation changes, it will just look like it's the same size (make sure to make another request for an ad in the willAnimateRotationToInterfaceOrientation: method to see this).
You don't need to do any moves, but you must set correct rootViewController for adMovView.
If you use view controller model please add line in each custom view controller
adMobView.rootViewController = viewController;
where viewController - root view controller of your app.
Do not code like this
adMobView.rootViewController = self;
in custom view!
I'm trying to attach a custom keyboard to a UITextField, and the keyboard would respond to different view orientations (landscape, portrait, etc). In short, the issue is that while the keyboard does show up, when responding to view orientation when I rotate the device, the dimensions of the keyboard is all messed up, and I'm not quite sure how to set the keyboard frame/bounds correctly. Hope someone here can give me a hand!
Here is my design:
The keyboard is built from a subclass of UIViewController (from xib). There are two views: landscapeKeyboardView and portraitKeyboardView.
The keyboard is attached to the UITextField through the property "inputView".
The rotation of the keyboard view is done in the function:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientationduration:(NSTimeInterval)duration
{
if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
{
self.view = self.landscapeKeyboardView;
}else if((toInterfaceOrientation == UIInterfaceOrientationPortrait) || (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
{
self.view = self.portraitKeyboardView;
}
}
The rotation does occur, but the view dimension is all messed up after the rotation. I have also tried to manually set the frame or the bounds of the view of either self.view or landscapeKeyboardView or portraitKeyboardView, and none of them seemed to solve the problem.
Does anyone know how to work around this issue? Or is there a much better design pattern for custom keyboards?
Thanks!
You probably need to translate the CGRect for rotation. UIView has a number of instance methods for converting rects and points. It accounts for views outside the frame of another view (to find out how far below a UIPopover the keyboard rect is, for example) as well as rotation. convertRect:fromView: is just one example, but they all start with 'convert'.