Submitting incorrect grades in landscape mode

I have a problem with landscape mode in the iPad app.

I created a very small new project to show my problem I set UIInterfaceOrientation to pList for UIInterfaceOrientationLandscapeRight

In the application delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self.window makeKeyAndVisible]; MyController *myController = [[MyController alloc] init]; [self.window addSubview:myController.view]; return YES; } 

In MyController

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSLog(@"Bounds Height:%f %f", self.view.bounds.size.height, self.view.bounds.size.width); } 

I also tried putting this in viewDidLoad with the same results

If I launch the application while holding the device in landscape orientation, NSLog displays

 Bounds Height: 1004.000000 Bounds Width: 768.000000 

What do I need to do to get the right results? I'm new to this iOS programming, all I am trying to do is snap the UISlider to the bottom of the screen, but when I get the wrong coordinates, I'm not sure how to do this.

+24
objective-c iphone cocoa-touch uikit
Mar 04 2018-11-11T00:
source share
9 answers

I do not think that the original question was answered, because Im experiencing the same problem.

The key here is that if the simulator / device is in landscape mode and then you run your program, self.view (frame or bounds) extracts the height and width of the portrait. If your program is already running and then you are turning, it gives the correct value. This only happens when the device starts in Landscape and does not rotate.

Has anyone else found a solution or know what I'm doing wrong? Please thanks.

Possible Solution

I previously called my method from the viewDidLoad method. It turns out that this view was still moving. I was lucky to call my function from viewDidAppear, which is called after everything is done.

Hope this helps.

+57
Jan 12 2018-12-12T00:
source share

You check the frame size and borders too quickly.

Instead, check them after rotation:

 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { NSLog(@"Bounds %@", NSStringFromCGRect(self.view.bounds)); NSLog(@"Frame %@", NSStringFromCGRect(self.view.frame)); } 

(Pay attention to my use of NSStringFromCGRect - convenient!)

This leads to the output:

 Bounds {{0, 0}, {1024, 748}} Frame {{0, 0}, {748, 1024}} 

So, in this release, the frame is “wrong,” but borders are what you expect. In fact, the frame is actually not the same as the way the frame calculations → are performed. Therefore, you need to access the borders.

See also maybe. Do I have the correct understanding of frames and borders in UIKit?

NB viewDidAppear gets a call sooner than you think in terms of things. According to Apple's docs: "viewDidAppear notifies the view controller that its view has been added to the window." In other words, this can happen before any rotation is applied.

+12
Mar 04 '11 at 16:27
source share

I had the same problem and hacked it like this:

 - (CGSize)getRotatedViewSize { BOOL isPortrait = UIInterfaceOrientationIsPortrait(self.interfaceOrientation); float max = MAX(self.view.bounds.size.width, self.view.bounds.size.height); float min = MIN(self.view.bounds.size.width, self.view.bounds.size.height); return (isPortrait ? CGSizeMake(min, max) : CGSizeMake(max, min)); } 
+10
Mar 13 '12 at 20:20
source share

viewWillAppear (according to lectures by Paul Hegarty CS193p) is intended for initializations related to geometry. Since viewDidAppear follows viewWillAppear, it makes sense that the borders here are also correct. View boundaries have not yet been set in viewDidLoad.

+2
Apr 18 '12 at 20:30
source share

Other viewDidAppear: use _window.rootViewController instead of [_window addSubview:_rootViewController.view] . It also solved my problems on iOS6.

AppDelegate.m:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; _rootViewController = [[MyRootViewController alloc] init]; _window.rootViewController = _rootViewController; [_window makeKeyAndVisible]; return YES; } 

MyRootViewController.m:

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSLog(@"bounds: %@", NSStringFromCGRect(self.view.bounds)); UIView *myView = [[UIView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:myView]; } 
+2
Jan 31 '13 at 20:23
source share

I created a small project for checking frames and borders because I had the same problem. Actually checking the bounds on viewDidLoad solved my problem.

I kept digging a bit and I found out that the borders are also correct in the viewWillLayoutSubviews method. Therefore, I assume that the most “correct” way to assemble your views in a project would be:

  • assign and create them to viewDidLoad or loadView with frames that you think will be fixed by then.

  • reformat the views you created in viewWillLayoutSubviews so that they are in the correct position when the view is actually displayed.

+1
Nov 08
source share

One of the comments on the accepted answer contained a solution to the problem for me.

There is a method that you can override on a UIViewController called viewDidLayoutSubviews, I applied it and adjusted my containing views.

And since its called after "viewWillAppear" and before "viewDidAppear" the changes you made to the subheadings are displayed as expected, no crashes.

+1
Jun 14 '14 at 21:24
source share

The same thing happened to me.

You need to entice iOS and put this line of code here, otherwise it will give the wrong answer.

 -(void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //required because device orientation will give you the wrong values [UIViewController attemptRotationToDeviceOrientation]; int orientation = [[UIDevice currentDevice] orientation]; BOOL isPortrait = false; if (orientation == 3 || orientation == 4) isPortrait = false; else isPortrait = true; NSLog(@"is portrait %i ?", isPortrait); } 
0
Aug 07 '14 at 15:19
source share
 UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; CGRect r = self.view.frame; CGFloat width = r.size.width; CGFloat height = r.size.height; r.size.height = (UIInterfaceOrientationIsLandscape(orientation)) ? MIN(width, height): MAX(width, height); r.size.width = (UIInterfaceOrientationIsLandscape(orientation)) ? MAX(width, height): MIN(width, height); self.view.frame = r; 
0
Feb 05 '15 at 17:15
source share



All Articles