Toolbar disappearing when loading page upside down - iphone

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.

Related

Scroll View in an Universal Xcode Project

I am creating an Universal app that has a scroll view.
The app runs fine for both the iPhone and iPad. However the scroll view is set to the iPad dimensions. So when i run the app on the iPhone the scroll view is still set for the iPad.
Any way I can change that?
You could use this:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[myScrollView setFrame:CGRectMake(0, 0, 320, 480)];
}else{
[myScrollView setFrame:CGRectMake(0, 0, 768, 1024)];
}
Of course you'll have to make adjustments to the scroll view's content size as well.

Navigation Bar issue in orientation

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.

UIImage/UIView Doesn't Adjust Properly To UIInterfaceLandscape Views

I am writing an app that I would like to only be viewed in Landscape Mode. I have set it up so that if the iPhone is held in Portrait Mode, nothing happens and the current image remains in Landscape Mode. The iPhone Simulator starts out in Landscape Mode with the Home Button on the right. If the iPhone is rotated from one Landscape Mode to the other, animation then occurs and the view is adjusted. However, whenever the device is in Landscape Mode with the Home Button on the left, the image is 20 pixels higher than needed, revealing a white line at the bottom of the screen.
In spite of all attempts to logically adjust this such as
self.view.frame = CGRectMake (0,20, self.view.frame.size.width, self.view.frame.size.height)
it doesn't fix the problem. I am accounting for the Status Bar in my calculations.
The .xib file contains an UIImageView on top of a UIView. This is my first experience implementing these methods so I apologize if the solution is relatively easy. Below is the code for the two methods used to implement the Landscape Mode views.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//set up interface to only be viewed in Landscape
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
return interfaceOrientation;
else if(interfaceOrientation == UIInterfaceOrientationLandscapeRight)
return interfaceOrientation;
else
return NO;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)tointerfaceOrientation duration:(NSTimeInterval)duration {
if(UIInterfaceOrientationLandscapeRight){
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
else if (UIInterfaceOrientationLandscapeLeft) {
//shouldn't adjustment to 20 fix the view?
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
else return;
}
For UIViews to adjust the subviews properly you will have to take a look at this UIView property: autoresizingMask, and set the mask to autoresize what is needed, if that does not work you will have to override:
- (void)layoutSubviews
From the reference: UIView reference

iPhone: app with only landscape and only portrait views

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.

Very Intermittent Orientation on Device & Simulator

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);
}
}