An advanced method for forcing a change in the orientation of a physical device in iOS

An advanced method for forcing a change in the orientation of a physical device in iOS

0x00 introduced

Apple doesn't expose a way to force the orientation of a physical device.
The most I can find on SO is:
NSNumber orientation = [NSNumber numberWithInt:targetOrientation];
[[UIDevice currentDevice] setValue:orientation forKey:@"orientation"]
This method uses the KVO mechanism and indirectly uses Apple's private method . However, multiple tests and verifications do not affect the listing review.

0x01 problem

There is a problem with the above setValue:forKey: method. If the target direction to be set is the same as the current physical device direction, the above method may not work.
For example: two view controllers A and B, where A supports landscape and portrait, B only supports landscape, when the direction from Portrait is pushed from A to B, force the direction of B to be LandscapeRight, and return from B to A , we also want A to be the Portrait direction. But if we rotate the device to the Portrait orientation on the B view controller, and then return to A, using the above setValue:forKey: method to force the physical device orientation to Portrait will not work, because at this time the physical device The direction is the same as the target direction to be set.

0x02 Reason guess

If the direction of the current physical device is consistent with the target direction to be set, the system may feel that there is no need to perform any operation (according to normal logic, it seems to be the case), and it may be directly returned in the internal implementation of the system (not verified). ,guess). However, business requirements often go beyond this, and we expect to be able to set physical devices to any target direction in any current direction.

0x03 problem solved

Since setting the target direction directly through setValue:forKey: does not work, I guess that you can first set an unknown direction to deceive the system, and then set the target direction. At this time, the target direction is different from the unknown direction, and the system will take effect.
Here's a way to force the orientation of the device:

- (void)forceToOrientation:(UIDeviceOrientation)orientation
{
    NSNumber *orientationUnknown = [NSNumber numberWithInt:0];
    [[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];

    NSNumber *orientationTarget = [NSNumber numberWithInt:orientation];
    [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
}

Verified on iOS7, 8, 9, it can perfectly solve the problem in the 0x01 example.
When Apple does not provide a valid public API, this approach basically achieves the goal of setting the physical device to any target orientation in any current orientation.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326403855&siteId=291194637