I searched every where but not find the solution of this I am New in iphone.In every where I got the set the height of navigation or my view is not rotating in orientation like issue.my view is rotating but my navigation bar is on same position please some one help me if You have solution.Thanks I have show my some code in down which I used for Orientation.when I tap on my tab bar my simulator is automatic rotate and I want tab bar also rotate but using this code only simulator is rotate not tab bar and navigation bar and sorry for my bad english.
CGAffineTransform transform = CGAffineTransformIdentity;
switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
transform = CGAffineTransformMakeRotation(M_PI_2);
break;
default:
break;
}
[[UIApplication sharedApplication]setStatusBarOrientation:UIInterfaceOrientationPortrait];
[UIView animateWithDuration:0.2f animations:^ {
[self.navigationController.view setTransform:transform];
}];
[self.view setFrame:CGRectMake(0, 0, 320, 480)];
[self.view setNeedsLayout];
This code is, no offense intended, very curious. I'm not sure what you are trying to do. What problem are you trying to solve? Playing around with CGAffineTransform's can definitely generate strange results like what you describe if you're not very careful.
If you just want to make sure that your app successfully supports landscape and portrait orientations, you can implement shouldAutorotateToInterfaceOrientation in your view controller. When you do this, all of the various controls will reorient themselves accordingly.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Support all orientations on iPad
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
return YES;
// otherwise, for iPhone, support portrait and landscape left and right
return ((interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
But if I have misunderstood what you're trying to do, i.e., you're trying to do something more sophisticated than just supporting both landscape and portrait orientation, let me know.
I apologize because I don't remember where I originally got this code (but it's referenced in SO here), but the following can be used to force landscape orientation:
First, make sure that your shouldAutoRotateToInterfaceOrientation should read as follows:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight))
return YES;
else
return NO;
}
Second, in viewDidLoad, add the following code:
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]))
{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
}
For some reason, removing the view from the main window and then re-adding it forces it to query shouldAutorotateToInterfaceOrientation and set the orientation correctly. Given that this isn't an Apple approved approach, maybe one should refrain from using it, but it works for me. Your mileage may vary. But that SO discussion also refers to other techniques, too.
Related
I know similar questions have been asked before, but this is a more specific use case (controlling orientation from a static library, cannot write in root view controller).
I have a static library which adds UI elements as overlays to a passed view controller (the client's root view controller) as subviews. Problem is our UI elements support portrait orientation only, while our client's application may support both portrait and landscape. This is fine, as long as our UI elements don't autorotate when our client's views do.
I'd like to lock the orientation to portrait only for our view controller only. In iOS 6, when I use the following code in my library's view controller, it doesn't affect the behaviour of autorotate at all:
-(BOOL)shouldAutorotate{
return NO;
}
-(NSInteger)supportedInterfaceOrientations{
NSInteger orientationMask = 0;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationPortrait])
orientationMask |= UIInterfaceOrientationMaskPortrait;
return orientationMask;
}
When I put the same code in the root view controller, it works perfectly, with the app no longer auto-rotating. However, this is not an option for us since in production we will not have access to our client's root view controller. Is there a way to either lock view orientation from NOT a root view controller, or lock orientation for a single view controller only? Any other way of achieving what we need that I'm not thinking of? Hoping for solutions that work in iOS <= 6 if at all possible
You can't lock orientation only for one view controller in whole application . So you have to set transform angle with parent view frame on view launch and on change of orientation.
You add code for those view controller class
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
[[self view] setBounds:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width)];
CGFloat radians = atan2f(self.view.transform.b, self.view.transform.a);
if (radians!=M_PI_2) {
[[self view] setTransform:CGAffineTransformMakeRotation(M_PI_2)];
}
}
}
(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
[[self view] setBounds:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width)];
CGFloat radians = atan2f(self.view.transform.b, self.view.transform.a);
if (radians!=M_PI_2) {
[[self view] setTransform:CGAffineTransformMakeRotation(M_PI_2)];
}
}else{
[[self view] setBounds:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGFloat radians = atan2f(self.view.transform.b, self.view.transform.a);
if (radians!=0) {
[[self view] setTransform:CGAffineTransformMakeRotation(0)];
}
}
}
So this will almost certainly be a simple answer, but I can't for the life of me work it out!
Basically, I want my current app to be viewable in portrait only (for now at least) and either the right way up, or upside down. Everything works fine the right way up and when you rotate the iPad on a page, everything works fine, the page flips up as normal. But if you hold the iPad upside down (home button at the top) and click a button to load a new page, when the page loads the toolbar is not visible! I don't know if for some reason the toolbar is behind the rest of the content or if its not there. If you then rotate the iPad back to portrait, the toolbar appears and all is back to normal again!
Whats weirder is that on the iPhone, the toolbar is there when you load a page with an upside down iPhone!!
I've tried all sorts with the shouldAutorotateToInterfaceOrientation() and didRotateFromInterfaceOrientation() methods and with resizing/positioning on viewDidLoad depending on the orientation. But nothing seems to work at all!!
This is code I have in my viewDidLoad() method:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
NSLog(#"iPhone");
if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortrait)
{
self.view.frame = CGRectMake(0, 0, 320, 460);
}
else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown)
{
self.view.frame = CGRectMake(0, 20, 320, 460);
}
}
else
{
NSLog(#"iPad");
if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortrait)
{
self.view.frame = CGRectMake(0, 0, 768, 1024);
NSLog(#"iPad Portrait Up");
}
else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown)
{
self.view.frame = CGRectMake(0, 20, 768, 1024);
NSLog(#"iPad Portrait Upside Down");
}
}
I've tried similar things in the didRotateFromInterfaceOrientation() method but nothing is working!
Thanks in advance for any help and feel free to ask questions/request more code
Matt
I ran into similar problem and here is what I discovered. When You add a toolbar at the top of the iPad UIView xib file, its autosizing is default to set up as shown in figure below. The toolbar will always stick to the bottom instead of the top.
What I did is change it to stick to top as shown in figure below and it fixed my problem.
If you setup the toolbar programmatically, you need to update the autoresizingMask.
I am building an application with multiple UIViewControllers controlled by a RootViewController. Currently in the plist the application defaults to LandscapeRight.
Lets say I have the following files that can be loaded into the RootViewController:
IntroView (Landscape Right ONLY)
LandscapeView (Landscape Right ONLY)
PortraitView (Portrait ONLY)
I also added into the RootViewController's shouldAutorotateToInterfaceOrientation the following:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if ([currentClass class] == PortraitView.class) {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
} else {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
}
so all is well until I load in the PortraitView and in the viewWillAppear i add the following (similar to this thread
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) { //UIInterfaceOrientationLandscapeRight) {
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
self.view.bounds = CGRectMake(0.0, 0.0, 320, 480);
self.view.center = CGPointMake(240.0f, 160.0f);
}
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
This yields a properly loaded in PortraitView but now my issue is that within my PortraitView I have 2 subviews that I would like to flip between, but because I rotated my view UIViewAnimationTransitionFlipFromLeft actually makes it flip top to bottom instead of left to right. I cannot for the life of me figure out how to tell PortraitView that its in Portrait.
When I check [[UIDevice currentDevice] orientation]; it tells me its in Landscape. When I attempt to use shouldAutorotateToInterfaceOrientation and set it to Portrait only it will then rotate my view so it is no longer correct.
Hopefully this makes sense! Been looking at this issue all day.
Thanks!
I ran into this slightly differently; a UIViewController subclass in landscape mode that swapped top-to-bottom instead of left-to-right.
The fix that worked for me was to add all my views to a single “inner” view and then flip that instead of the UIViewController’s normal view.
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:[self innerView]
cache:YES];
Where [self innerView] is the sole child of [self view], and all the subviews are inside of it.
I've noticed that I'm getting very intermittent orientation on my device & the simulator.
I have a modal view controller that I present, and that is the only thing in my app which supports rotation.
If I launch the app in portrait without moving the device, open the modal VC and then rotate the device, it usually works. However sometimes if I open the app holding the device in landscape, then rotate to portrait, launch the VC and then rotate the device, no rotation occurs. It seems very intermittent. Sometimes if I launch the app in portrait mode and then open the VC and rotate the device, nothing happens, and until I quit and relaunch it no orientation occurs in the app.
It's strange because 50% of the time it works! Whenever I launch it through Xcode and set breakpoints in shouldAutorotateToInterfaceOrientation it always works!
Anyone ever had this or know what's going on?
Since as you mentioned "intermittent", i would say it has something to do with what are you doing after the rotation.
To find the bug, i suggest removing any code after the rotation happens. Comment out any network activities or OpenGL operations. Could also help to close XCode and reopen it.
If nothing helps, i would make a new project and start moving the files one by one and test.
I've had similar challenges getting autorotation to work properly for view controllers whose parent view controllers don't autorotate, although most of my experience has related to wrangling UINavigationController as opposed to modal view controllers. Still, I'd recommend trying the following:
Call presentModalViewController: on the top level view controller in your hierarchy rather than a deeper viewController.
If that doesn't solve it, try subclassing your top level view controller, and overriding its shouldAutorotateToInterfaceOrientation: to look something like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (self.modalViewController) {
return [self.modalViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
Does calling
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
when you show your rotation-aware view help? (and possibly turning it off again when you dismiss it?)
The other thing I would look for is suspicious calls to [UIWindow makeKeyWindow] or [UIResponder becomeFirstResponder].
I'd also sign up for UIDeviceOrientationDidChangeNotification events and make sure that the Modal view got a call to [UIViewController shouldAutorotateToInterfaceOrientation:] for each event you receive.
I've finally discovered what the problem was!
It turns out that only the very first UIView you add to your UIWindow will get asked whether or not to rotate. Any subsequent views don't receive this message. My app was using another view to animate away from the Default.png that is displayed on launch, and this was added to the window first!
Even if you try to launch your application in landscape, your phone will launch it in portrait and then go into landscape depending in which position your phone is.
I don't know what code you are using to accomplish this. Below is one which is taken from Apple code snippets. See if this can help.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)
interfaceOrientation duration:(NSTimeInterval)duration {
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
self.view = self.portrait;
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
self.view.bounds = CGRectMake(0.0, 0.0, 300.0, 480.0);
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
self.view = self.landscape;
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
self.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
}
else if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.view = self.portrait;
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(180));
self.view.bounds = CGRectMake(0.0, 0.0, 300.0, 480.0);
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
self.view = self.landscape;
self.view.transform = CGAffineTransformIdentity;
self.view.transform =
CGAffineTransformMakeRotation(degreesToRadian(90));
self.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
}
}
I have a simple UIViewController that uses a XIB for its interface.
As such, the interface simply comprises a UIView, a UIActivityIndicator and a UILabel. I have the sizing constraints in Interface Builder set to keep the activity indicator and the label centred when the view rotates.
The UIViewController is set to return YES for portrait and landscape orientations in the -shouldAutorotateToInterfaceOrientation: method.
The view is added to the view hierarchy manually, using
if (!activityOverlay)
activityOverlay = [[XBActivityOverlayViewController alloc] initWithNibName:#"XBActivityOverlayViewController" bundle:nil message:#"Connecting..."];
[activityOverlay.view setAlpha:0.0f];
[self.window addSubview:activityOverlay.view];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f];
[activityOverlay.view setAlpha:0.9f];
[UIView commitAnimations];
The problem I'm having is that if the device is already in landscape orientation and the view is added to the hierarchy at this point, the view is still in portrait orientation, and doesn't auto rotate.
What do I need to do to add the view in the same orientation as the parent view?
I do not know if it is the right answer to your question but I hope can help:
For me, every time I add/dismiss a modal or display a new view, the following function is called:
-(void) detectOrientation
{
if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight))
{
item1.frame = CGRectMake(147.0, 241.0, 56.0, 28.0);
item2.frame = CGRectMake(265.0, 241.0, 56.0, 28.0);
}
else if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) || !inLandscapeOrientation)
{
item1.frame = CGRectMake(35.0, 425.0, 35.0, 28.0);
item2.frame = CGRectMake(176.0, 425.0, 35.0, 28.0);
}
}
Here I change the position according to the current device orientation. Maybe if you detect that the current orientation is landscape you add a subview that has such orientation.
Alejandra :)