How do I create an application using the Single View application template where the main window does not run but the rest?

advertisements

How to create an App using the Single View App template where the main window does not rotate but its rootViewController and everything else autorotates?

Apple does that on CIFunHouse but because the code is poorly explained in that matter, it is impossible to know how they did it. If you run the app you will see that the camera's preview window does not autorotate because the preview was added to the window but everything else does.

Apple uses this technique on their native iPad camera app.


So the answer is not clean but I can give you a fix. At some point the main application window must not have autorotated like it does now but at some point it started rotating according to the rootviewcontroller. At least this source code suggests that. I started developing at the end of iOS 6 and I think this source was written about that time. The best fix I could find for allowing everything to rotate in the example for me but having the preview to not rotate was to add a second window. Set the main window background to clear. Then add the previewLayer to the second window behind the main window. In code it would look like this.

The AppDelegate looked like this.

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>

@interface FHAppDelegate : UIResponder <UIApplicationDelegate>
{
@private
  CMMotionManager *_motionManager;
}
@property (strong, readonly, nonatomic) CMMotionManager *motionManager;
//future preview window
@property (strong, nonatomic) UIWindow *previewWindow;
@property (assign, readonly, nonatomic) UIDeviceOrientation realDeviceOrientation;

@end

Then in the viewDidLoad of the FHViewController instead of adding to the main window I did this and it added where they get the main window I add the previewView to that.

   // we make our video preview view a subview of the window, and send it to the back; this makes FHViewController's view (and its UI elements) on top of the video preview, and also makes video preview unaffected by device rotation
   //nothing special about this viewcontorller except it has
   //-(BOOL)shouldAutorotate{
   //return NO;
   //}

    TestViewController *test = [[TestViewController alloc]initWithNibName:@"TestViewController" bundle:nil];
    FHAppDelegate *delegate = ((FHAppDelegate *)[UIApplication sharedApplication].delegate);
    delegate.previewWindow = [[UIWindow alloc]initWithFrame:window.bounds];
    UIWindow *previewWindow = delegate.previewWindow;
    [window setBackgroundColor:[UIColor clearColor]];

    previewWindow.rootViewController = test;
    previewWindow.windowLevel = UIWindowLevelNormal - 1;

    [previewWindow setBounds:delegate.window.bounds];

    [previewWindow makeKeyAndVisible];
    [previewWindow addSubview:_videoPreviewView];
    [previewWindow sendSubviewToBack:_videoPreviewView];

Because the previewWindow has to have a rootviewcontroller and it determines the rotation you can see my testviewcontroller has autorotate of NO. Hope this helps. It is working for me on iOS 10.

Edit: The view in the example above does not rotate but the window animation on rotation is bad visually. It can be removed by overriding willTransitionToSize

    [UIView setAnimationsEnabled:NO];

and after completion

[UIView setAnimationsEnabled:YES];

See swift version on GitHub

For an iPad requires Full Screen must be check.