Reporting incorrect bounds in landscape Mode

前端 未结 9 1103
青春惊慌失措
青春惊慌失措 2020-12-05 02:57

I am having an issue with Landscape mode in my iPad application.

I created a very small new project to show my issue I set UIInterfaceOrientation in the pList to UII

相关标签:
9条回答
  • 2020-12-05 03:20

    You're checking the frame and bounds size too soon.

    Instead, check them after rotation:

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

    (Note my use of NSStringFromCGRect -- handy!)

    This produces the output:

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

    So in this output the frame is 'wrong', but the bounds are what you expect. In fact, the frame isn't actually wrong, that's just how frame -> bounds calculations happen. So you need to access the bounds.

    See also perhaps Do I have the right understanding of frames and bounds in UIKit?

    N.B. viewDidAppear gets called sooner than you think in the scheme of things. According to Apple docs: "viewDidAppear notifies the view controller that its view was added to a window." In other words, it can happen before any rotation is applied.

    0 讨论(0)
  • 2020-12-05 03:22

    I had the same thing happen to me.

    You have to spoon-feed iOS and put this line of code here or else it will give you 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 讨论(0)
  • 2020-12-05 03:23

    Apart from viewDidAppear: make sure using _window.rootViewController instead of [_window addSubview:_rootViewController.view]. That also solved my issues 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];
    }
    
    0 讨论(0)
  • 2020-12-05 03:28

    I dont think the original question was answered here because Im experiencing the same issue.

    The key here is that if the simulator / device is in Landscape mode, and Then you start your program, self.view.(frame or bounds) retrieves the Portrait height and width. If your program is already running and then you rotate it gives the correct value. This only occurs when the device is started in Landscape and is not rotated.

    Has anyone else found a solution to this or knows what Im doing wrong? Please & Thank you.

    Possible Solution

    I had previously been calling my method from the viewDidLoad method. It turns out that the view was still transitioning. I had better luck by calling my function from viewDidAppear that is called after everything is done.

    Hope that helps.

    0 讨论(0)
  • 2020-12-05 03:29

    I had the same problem and hacked it like so:

    - (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));            
    }
    
    0 讨论(0)
  • 2020-12-05 03:30
    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 讨论(0)
提交回复
热议问题