Sti
Sti

Reputation: 8484

How can I get the correct size of my UIView?

Question 1:

How do I get the correct size of a UIView?

I am creating a CGRect to show some images using tiled layers. When I'm creating the CGRect, I basically need it to be the exact same size as that of my UIView. This turned out to be quite hard.. When I NSLog() out my mainView.bounds.size.width or my mainView.frame.size.width they are always wrong when in landscape! They always log out the values as if it was in portrait, even though I can see the actual view being wider. And reversing them will also be wrong. It's not good enough set the width to be the height and vice versa when in landscape, I need the right values.

The only way I've been able to make it look right is to manually put in 1024 for width when in Landscape, and this doesn't always work either, because:

Question 2:

What is the correct way to check if the device is in landscape or not?

I've been using

if([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight)

but this doesn't always work. If I hold my device in landscape mode when launching, it is correct, but if I make it landscape, then lay the iPad flat down leaving the dashboard as landscape and THEN launch it, then the landscape-splash shows up, but that code think it's in portrait. That code doesn't work at all for iPad simulator either..

EDIT

For some reason, when I decided to add support for landscape orientation, it wasn't enough to just check the landscape-orientations in the summary-page of the target, I had to actually sub-class my TabBarController and physically tell it to rotate with

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return YES;
}

I shouldn't have to do this.. right? If I create an empty project like that, it doesn't need it.. I don't know why.

Upvotes: 0

Views: 246

Answers (2)

lnafziger
lnafziger

Reputation: 25740

Question 1: Yup, that's right. :)

Question 2: I just got home and checked my own code. I use:

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

to check the orientation of the current interface. Then, you can use something like:

if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    // Do something
} else if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){
    // Do something else
}

HOWEVER You really should not need to do this if you properly handle rotation events.

Here is my typical way of dealing with rotation when I need to adjust UI element positions in code based on orientation:

#pragma mark - View rotation methods

// Maintain pre-iOS 6 support:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

// Make sure that our subviews get moved on launch:
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self moveSubviewsToOrientation:orientation duration:0.0];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self moveSubviewsToOrientation:toInterfaceOrientation duration:duration];
}

// Animate the movements
- (void)moveSubviewsToOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
{
    [UIView animateWithDuration:duration
                     animations:^{
                         [self.tableView reloadData];
                         if (UIInterfaceOrientationIsPortrait(orientation))
                         {
                             [self moveSubviewsToPortrait];
                         }
                         else
                         {
                             [self moveSubviewsToLandscape];
                         }
                     }
                     completion:NULL];
}

- (void)moveSubviewsToPortrait
{
    // Set the frames/etc for portrait presentation
    self.logoImageView.frame = CGRectMake(229.0, 21.0, 309.0, 55.0);
}

- (void)moveSubviewsToLandscape
{
    // Set the frames/etc for landscape presentation
    self.logoImageView.frame = CGRectMake(88.0, 21.0, 309.0, 55.0);
}

I also put moveSubviewsToOrientation in viewWillAppear to have it rotate

Upvotes: 1

Khaled Barazi
Khaled Barazi

Reputation: 8741

I struggled with this a bit and here are some facts I found:

1- When a device is face up or down, the device reverts to the last orientation prior to it being face up or down since those 2 orientations do not tell you necessarily on their own whether the device is portrait or landscape. So for example, if you were in landscape and then put the device flat face up, then launch an app, it will launch in the landscape orientation.

2- When viewDidLoad is called, the bounds have not been set, so you need to put any calls that pertain to the orientation in viewWillAppear or viewDidLayoutSubviews.

3- If for some odd reason, you need to use the bounds before viewDidLoad, or maybe to do something in a model, I have found that the best way to put settings that pertain to the orientation is to trust the statusbar, which you can call as follows for example.

if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))

PS: Regarding your added question, refer to: https://developer.apple.com/library/ios/#qa/qa2010/qa1688.html

You are most likely one of the last 2 bullets. I ran into this issue before and quite frankly found it easiest to just implement:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;

for all VCs just to be on the safe side especially that the behaviour has changed from iOS5 to iOS6.

http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDeviceOrientationChanges/RespondingtoDeviceOrientationChanges.html#//apple_ref/doc/uid/TP40007457-CH7-SW1

Hope this helps

Upvotes: 1

Related Questions