开发者

Is there a way to determine device orientation if view is loaded before [window makeKeyAndVisible] is called?

开发者 https://www.devze.com 2023-03-16 07:18 出处:网络
View of my UIViewController is loaded from a NIB before [window makeKeyAndVisible] is called in application:didFinishLaunchingWithOptions: so I cannot get the correct device orientation - i.e. self.in

View of my UIViewController is loaded from a NIB before [window makeKeyAndVisible] is called in application:didFinishLaunchingWithOptions: so I cannot get the correct device orientation - i.e. self.interfaceOrientation, [[UIApplication sharedApplication] statusBarOrientation] and [[UIDevice currentDevice] orientation] all give me false orientation info that I'm in portrait mode (iPad's default mode, I think).

Is there any way开发者_运维技巧 to work around that problem? Please don't say I need to use accelerometer ;)

EDIT: for whose who are interested on getting orientation info based on accelerometer reading: http://web.archive.org/web/20091111033649/http://blog.sallarp.com/iphone-accelerometer-device-orientation


it appears that you can't rely on [UIDevice currentDevice].orientation until the orientation actually changes for the first time. If so, you could probably hack it by getting raw accelerometer readings.

#define kUpdateFrequency 30  // Hz
#define kUpdateCount 15 // So we init after half a second
#define kFilteringFactor (1.0f / kUpdateCount)

- (void)applicationDidFinishLaunching:(UIApplication *)app
{
    [UIAccelerometer sharedAccelerometer].updateInterval = (1.0 / kUpdateFrequency);
    [UIAccelerometer sharedAccelerometer].delegate = self;
    accelerometerCounter = 0;
    ...
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)accel
{
    // Average out the first kUpdateCount readings
    // acceleration_[xyz] are ivars typed float
    acceleration_x = (float)accel.x * kFilteringFactor + acceleration_x * (1.0f - kFilteringFactor);
    acceleration_y = (float)accel.y * kFilteringFactor + acceleration_y * (1.0f - kFilteringFactor);
    acceleration_z = (float)accel.z * kFilteringFactor + acceleration_z * (1.0f - kFilteringFactor);

    accelerometerCounter++;
    if (accelerometerCounter == kUpdateCount)
    {
        [self initOrientation];
        [UIAccelerometer sharedAccelerometer].delegate = nil;
    }
}

- (void)initOrientation
{
    // Figure out orientation from acceleration_[xyz] and set up your UI...
}

Original response:

Does [UIDevice currentDevice].orientation return the correct orientation during applicationDidFinishLaunching:? If so, you can set up your initial UI according to that orientation.

If that property doesn't get set until some later time, you might try experimenting with performSelector:afterDelay: to initialize the UI after a small delay.

This code sample is from Kendall's answer below, added here for completeness:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];

I'm not sure if a zero-second delay is sufficient -- this means the code for getOriented will run during the first pass through the event run loop. You may need to wait longer for the accelerometer readings to register on UIDevice.


I found that the only workable solution was to implement layoutSubviews for the main view and do the reorientation of the layout there (via a call back into my view controller).

Once you're at that point UIViewController.interfaceOrientation appears to be reliable.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号