This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
iPhone orientation
Depending on what orientation the iPad is in, I need to either set the table view's background or remove it because it doesn't work with the popover.
I tried this but no luck:
if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft ){
self.navigationController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
self.tableView.backgroundColor = [UIColor clearColor];
NSLog(#"test");
Maybe there is a better way? To see if table is master or popover, then set background?
There are several ways to achieve what you want, more or less:
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
A more hack-ish method would be to check the width of the status bar.
If you go with option 1, then you can check the orientation like so:
switch (orientation) {
case UIInterfaceOrientationPortrait:
// Do something.
break;
case UIInterfaceOrientationPortraitUpsideDown:
// Do something.
break;
case UIInterfaceOrientationLandscapeLeft:
// Do something.
break;
case UIInterfaceOrientationLandscapeRight:
// Do something.
break;
}
EDIT: To get your application to automatically rotate, you can do this:
- (BOOL)willAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if ((interfaceOrientation == UIDeviceOrientationLandscapeRight)) NSLog(#"Right");
if ((interfaceOrientation == UIDeviceOrientationLandscapeLeft)) NSLog(#"Left");
if ((interfaceOrientation == UIDeviceOrientationPortrait)) NSLog(#"Up");
if ((interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)) NSLog(#"Down");
return YES;
}
UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;
Related
I'm developing a universal app.
When my device is ipad I have 2 designs: Portrait and landscape.
I use this method: -(void)orientationDidChanged:(NSNotification *)notification
It works perfectly when I rotated my device. But I have a problem, when first load the view and I have not rotated the device.
For that reason, I put this code in the viewdidload:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){ //
something.
}
else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
NSLog(#"IPAD ** ");
if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
NSLog(#" vertical ** ");
}
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Horizontal ** ");
}
}
My problems is this: sometimes it works , sometimes not :(. This method: orientationDidChanged, when start to work? only if I rotate my device or immediately with the viewDidLoad , is necessary ask one more time the orientation when I have that method? Thanks for some advice.
I don't have problem when I rotated my device, it works perfectly :D .. My problem is when I recently run the application and I haven't turned the device
You can use this:
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == 0) //Default orientation
//UI is in Default orientation (Portrait)
else if(orientation == UIInterfaceOrientationPortrait)
//UI is in Portrait orientation
else if(orientation == UIInterfaceOrientationLandscapeLeft)
//UI is in Landscape-left orientation
else if(orientation == UIInterfaceOrientationLandscapeRight)
//UI is in Landscape-right orientation
I have a splitViewController. This is in Detail VC
-(void)viewDidLoad
{
self.masterIsVisible = YES;
//a botton in navigation bar to hide or show the master view.
[button addTarget:self action:#selector(showOrHideMasterView)
forControlEventsTouchUpInside]
//gesture control to swipe right or left to slide master view in and out.
[swiperight addTarget:self action:#selector(showMasterView)];
[swipLeft addTarget:self action:#selector(hideMasterView)];
}
-(void)showOrHideMasterView
{
if (self.masterIsVisible)
[self hidemasterView]; self.masterIsVisible = NO;
else
[self showMasterView]; self.masterIsVisible = YES;
}
-(void)hideMasterView
{
//hides master view by substracting masterview's width from its origin.x
}
-(void)showMasterView
{
//shows master View by adding masterview's width to its origin.x
}
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
Everything almost works as intended.
Problem: In one orientation && master is NOT visible.. then device changes orientation.. the master View instead of sliding off the screen pushed the detail view the other way. I know thats because the flag now is set as masterIsVisible = NO instead of YES. What can I do to change the flag to YES on device rotation. looks trivial but cant seem to figure out.
I tried registering for devicechnagenotification in UIDevice but that did not work. The BOOL is YES in any Orientation. The apple example uses this but looks like thats not the right approach here.
Ok, I finally figured out to set the flag correctly for orientation change. I added the following method
-(void)willAnimateRotationToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
self.masterIsVisible = NO;
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
self.masterIsVisible = YES;
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
self.masterIsVisible = YES;
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
self.masterIsVisible = NO;
}
I have a universal application created in storyboard mode. It is set-up to automatically rotate to the current orientation. I have attempted to disable some orientations in iPhone-mode but it does not work when I test in the simulator.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return ((interfaceOrientation != UIInterfaceOrientationLandscapeRight) || (interfaceOrientation != UIInterfaceOrientationLandscapeLeft));
} else {
return YES;
}
}
Also, when the iPad is rotated, it should go through the following code BUT all I get is a black screen.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.view = landscape;
self.view.transform = CGAffineTransformMakeRotation(deg2rad*(90));
self.view.bounds = CGRectMake(0.0, 0.0, 1024.0, 748.0);
} else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
self.view = landscape;
self.view.transform = CGAffineTransformMakeRotation(deg2rad*(-90));
self.view.bounds = CGRectMake(0.0, 0.0, 1024.0, 748.0);
} else {
self.view = portrait;
self.view.transform = CGAffineTransformMakeRotation(0);
self.view.bounds = CGRectMake(0.0, 0.0, 768.0, 1004.0);
}
} else {
}
}
Why are all these problems arising here? I have tried the code in different Xcode projects without storyboards ad it works fine. What is going on and how can I fix this?
You should create two separate stackoverflow questions. I will answer your first question here.
Consider this line from your code:
return ((interfaceOrientation != UIInterfaceOrientationLandscapeRight) || (interfaceOrientation != UIInterfaceOrientationLandscapeLeft));
If the orientation is Right, then your code reduces to return (Right != Right) || (Right != Left), which always returns true.
If the orientation is Left, then your code reduces to return (Left != Right) || (Left != Left), which always returns true.
If the orientation is Up, then your code reduces to return (Up != Right) || (Up != Left), which always returns true.
If the orientation is Down, then your code reduces to return (Down != Right) || (Down != Left), which always returns true.
It's not clear which orientations you want to allow and which you want to exclude. If you want to allow only portrait orientations, do this:
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
If you want to allow only landscape orientations, do this:
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
Currently I'm workign on a drawing app for the iPad. I need to reposition and rotate the toolbar in the app when it is put into a different orientation while keeping the the drawing area in the same place.
I found a method here for doing this. It uses the NSNotificationCenter to monitor for rotation changes. This calls a custom didRotate: method that will rotate and reposition my toolbar based on the UIDeviceOrientation.
This part works fine. However, whenever the side switch on the iPad is engaged to lock the orientation, the toolbar repositions to the location is was at launch.
For example: If I start the application in landscape left and rotate it to portrait, the toolbar will reposition to the bottom of the screen. However as soon as I engage the slide switch, it moves to the side of the screen for the landscape left orientation.
The methods I'm using for this are all below.
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)didRotate:(NSNotification *)notification {
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
UIInterfaceOrientation interfaceOrientation;
bool orientationFound = YES;
if (deviceOrientation == UIDeviceOrientationPortrait) {
interfaceOrientation = UIInterfaceOrientationPortrait;
} else if (deviceOrientation == UIDeviceOrientationPortraitUpsideDown) {
interfaceOrientation = UIInterfaceOrientationPortraitUpsideDown;
} else if (deviceOrientation == UIDeviceOrientationLandscapeLeft) {
interfaceOrientation = UIInterfaceOrientationLandscapeRight;
} else if (deviceOrientation == UIDeviceOrientationLandscapeRight) {
interfaceOrientation = UIInterfaceOrientationLandscapeLeft;
} else {
orientationFound = NO;
}
if (orientationFound) {
[self.toolbar changeToOrientation:interfaceOrientation withDuration:.25];
[self.tutorialOverlay changeToOrientation:interfaceOrientation];
}
}
- (void)changeToOrientation:(UIInterfaceOrientation)orientation withDuration:(float)duration {
float angle;
CGPoint origin;
if (orientation == UIInterfaceOrientationPortrait) {
angle = portraitAngle;
origin = self.portraitOrigin;
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
angle = portraitUpsideDownAngle;
origin = self.portraitUpsideDownOrigin;
} else if (orientation == UIInterfaceOrientationLandscapeLeft) {
angle = landscapeLeftAngle;
origin = self.landscapeLeftOrigin;
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
angle = landscapeRightAngle;
origin = self.landscapeRightOrigin;
}
[UIView animateWithDuration:duration animations:^{
self.transform = CGAffineTransformMakeRotation(angle);
CGRect rect = self.frame;
rect.origin = origin;
self.frame = rect;
}];
}
I'd strongly recommend against using this notification-based approach. Note that the name of the notification is UIDeviceOrientationDidChangeNotification; the device orientation is not the same as the interface orientation, and it leads to lots of little issues like this. (The device orientation, for example, includes UIDeviceOrientationFaceDown, which is never associated with an interface orientation.)
I'd suggest letting your view controller automatically rotate itself; this will place the toolbar, etc, for you. You can then override - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration to put the drawing area back to the orientation you want to maintain. (You'd use similar code to your changeToOrientation method above, but for the drawing area instead, and you don't need to create your own animation block. Also, the angles would all be negated, because you're undoing the change the view controller made.)
I just answered a similar question here.
Basically just allow the interface to rotate, but rotate the view you don't want to rotate 'back' in willRotateToInterfaceOrientation:duration:.
Hey all. I have a fairly simple question. I am developing a "rich" iPad app, and I have two background images specifically designed for landscape and portrait. I'd like this ImageView to automatically change depending on the devices orientation. (like pretty much all of Apples iPad apps).
Can anyone point me in the right direction? I'm assuming it would be something I do on viewDidLoad..
The best thing you can do is to change the frames of your subview frames according to your interface orientations. You can do it like:
#pragma mark -
#pragma mark InterfaceOrientationMethods
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (UIInterfaceOrientationIsPortrait(interfaceOrientation) || UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
//self.view = portraitView;
[self changeTheViewToPortrait:YES andDuration:duration];
}
else if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)){
//self.view = landscapeView;
[self changeTheViewToPortrait:NO andDuration:duration];
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------
- (void) changeTheViewToPortrait:(BOOL)portrait andDuration:(NSTimeInterval)duration{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
if(portrait){
//change the view and subview frames for the portrait view
}
else{
//change the view and subview frames for the landscape view
}
[UIView commitAnimations];
}
Hope this helps.
I actually figured out a very simple alternative way around this. Since I am just changing the background image, adding this..
`
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration {
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation ==
UIInterfaceOrientationPortraitUpsideDown) {
[brownBackground setImage:[UIImage imageNamed:#"Portrait_Background.png"]];
} else {
[brownBackground setImage:[UIImage imageNamed:#"Landscape_Background.png"]];
}
}
`
Changes the background of a declared UIImageView based on orientation. Only downside is, the current background image is not visible in Interface builder as it is handled with code.
One small addition to Madhup's approach, which is great. I found I needed to add this to viewDidLoad to set initial background image for portrait or landscape:
// set background image
if (self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"portraitBG.png"]];
} else {
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"landscapeBG.png"]];
}
thanks again Madhup
You can encapsulate this entirely in your UIView by watching whether bounds.width > bounds.height
This may be desirable if you're writing a small, self aware control.
class MyView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
if bounds.height > bounds.width {
println("PORTRAIT. some bounds-impacting event happened")
} else {
println("LANDSCAPE")
}
}
}