Orientation of the Force View controller in iOS 9

I am working on a photographic application that allows you to take pictures in portrait or landscape orientation. Due to the requirements of the project, I cannot allow authorizing the orientation of the device, but the rotation must be maintained.

Using the following orientation methods:

override func shouldAutorotate() -> Bool { return true } override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { if self.orientation == .Landscape { return UIInterfaceOrientationMask.LandscapeRight } else { return UIInterfaceOrientationMask.Portrait } } override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation { if self.orientation == .Landscape { return UIInterfaceOrientation.LandscapeRight } else { return UIInterfaceOrientation.Portrait } } 

I can set rotation on startup correctly. By changing the orientation value and calling UIViewController.attemptRotationToDeviceOrientation() , I can support rotation to the new desired interface. However, this rotation occurs only when the user actually moves his device. I need this to happen automatically.

I can call: UIDevice.currentDevice().setValue(targetOrientation.rawValue, forKey: "orientation") to force a change, but it causes other side effects because UIDevice.currentDevice().orientation returns the value of setValue from this point. (and he is very dirty)

Is there something I am missing? I studied closing and starting a new view controller, but it has other problems, such as the user interface constantly crashing when the controller declines and immediately presents a new view.

EDIT:

The following methods did not work for me:

EDIT 2:

Thoughts on potential solutions:

  • set the orientation directly (using setValue ) and consider all the side effects it presents on iOS 9 (unacceptable)

  • I can use the current solution and indicate that the user needs to rotate the device. After the device is physically rotated, the user interface is rotated and then fixed correctly. (bad interface)

  • I can find a solution that forces me to update the orientation and rotates without physical impact. (what I ask and seek)

  • Do it all manually. I can lock the interface in portrait or landscape orientation and manually rotate and resize the container view. This is dirty because it discards all autorun functions of the size class and calls much more heavy code. I try to avoid this.

+6
source share
3 answers

I managed to find a solution using this answer: Changing the orientation of the program interface does not work for iOS

My base orientation logic is as follows:

 // Local variable to tracking allowed orientation. I have specific landscape and // portrait targets and did not want to remember which I was supporting enum MyOrientations { case Landscape case Portrait } var orientation: MyOrientations = .Landscape // MARK: - Orientation Methods override func shouldAutorotate() -> Bool { return true } override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { if self.orientation == .Landscape { return UIInterfaceOrientationMask.LandscapeRight } else { return UIInterfaceOrientationMask.Portrait } } override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation { if self.orientation == .Landscape { return UIInterfaceOrientation.LandscapeRight } else { return UIInterfaceOrientation.Portrait } } // Called on region and delegate setters func refreshOrientation() { if let newOrientation = self.delegate?.getOrientation() { self.orientation = newOrientation } } 

Then, when I want to update the orientation, I do the following:

 // Correct Orientation let oldOrientation = self.orientation self.refreshOrientation() if self.orientation != oldOrientation { dispatch_async(dispatch_get_main_queue(), { self.orientationRefreshing = true let vc = UIViewController() UIViewController.attemptRotationToDeviceOrientation() self.presentViewController(vc, animated: false, completion: nil) UIView.animateWithDuration(0.3, animations: { vc.dismissViewControllerAnimated(false, completion: nil) }) }) } 

This solution has a side effect that triggers the view[Will/Did]Appear and view[Will/Did]Disappear . I use the local variable orientationRefreshing to control which aspects of these methods are called again.

+3
source

I encountered this exact problem in the past myself. I was able to solve this using simple operation (and GPUImage ). My code is in Objective-C, but I’m sure it’s easy for you to translate it into Swift.

I started by installing project-supported rotations to everything I was hoping to support, and then overriding the same UIViewController methods:

 -(BOOL)shouldAutorotate { return TRUE; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 

Allows the device to rotate, but will be saved in portrait mode. Then he began to observe the rotation of the device:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(adjustForRotation:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

Then he updated the user interface if the device was in portrait mode or in landscape orientation:

 -(void)adjustForRotation:(NSNotification*)notification { UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; switch (orientation) { case UIDeviceOrientationLandscapeLeft: { // UPDATE UI } break; case UIDeviceOrientationLandscapeRight: { // UPDATE UI } break; default: // All other orientations - Portrait, Upside Down, Unknown { // UPDATE UI } break; } } 

And finally, GPUImage displayed an image based on the orientation of the device.

 [_gpuImageStillCamera capturePhotoAsImageProcessedUpToFilter:last_f withCompletionHandler:^(UIImage *processedImage, NSError *error) { // Process the processedImage }]; 
+3
source

So, I looked at the private headers of UIDevice , and it seems that there are two setters and two property definitions for orientation, which currently puzzles me. This is what I saw ...

 @property (nonatomic) int orientation; @property (nonatomic, readonly) int orientation; - (void)setOrientation:(int)arg1; - (void)setOrientation:(int)arg1 animated:(BOOL)arg2; 

So, when I saw that you used setValue:forKey: I wanted to see that there is a synthesized setter and getter, and I'm honestly not 100% sure about which one is installed and which one is confirmed by the device ... I tried in the demo application to use setValue:forKey: no avail, but used this trick from one of my past applications and it did the trick right away :) I hope this helps

 UIDevice.currentDevice().performSelector(Selector("setOrientation:"), withObject: UIInterfaceOrientation.Portrait.rawValue) 
0
source

All Articles