如何使用单视图应用程序模板创建应用程序,其中主窗口不旋转但其余部分?

时间:2017-03-12 19:55:56

标签: ios camera avfoundation uiwindow auto-rotation

如何使用单视图应用程序模板创建应用程序,其中主窗口不旋转,但其rootViewController和其他所有内容都会自动旋转?

Apple在CIFunHouse上做到了这一点,但由于代码在这方面的解释很差,因此无法知道他们是如何做到的。如果您运行该应用程序,您将看到相机的预览窗口不会自动旋转,因为预览已添加到窗口,但其他所有内容都已添加。

Apple在他们原生的iPad相机应用程序上使用这种技术。

2 个答案:

答案 0 :(得分:1)

所以答案不是很干净,但我可以给你一个解决方法。在某些时候,主应用程序窗口必须不像现在那样自动旋转,但在某些时候它根据rootviewcontroller开始旋转。至少这个源代码表明了这一点。我在iOS 6结束时开始开发,我认为这个来源是关于那个时候编写的。我可以找到最好的修复方法,允许所有内容在我的示例中旋转,但预览不旋转是添加第二个窗口。将主窗口背景设置为清除。然后将previewLayer添加到主窗口后面的第二个窗口。在代码中它看起来像这样。

AppDelegate看起来像这样。

#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

然后在FHViewController的viewDidLoad中,而不是添加到主窗口,我做了这个,并且它添加到主窗口的地方,我将previewView添加到该窗口。

   // 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];

因为previewWindow必须有一个rootviewcontroller并且它确定了旋转,你可以看到我的testviewcontroller自动旋转为NO。希望这可以帮助。它在iOS 10上为我工作。

编辑:上面示例中的视图不会旋转,但旋转时的窗口动画在视觉上是不好的。它可以通过覆盖删除 willTransitionToSize

    [UIView setAnimationsEnabled:NO];

完成后

[UIView setAnimationsEnabled:YES];

请参阅GitHub

上的swift版本

对于iPad,必须检查全屏。

答案 1 :(得分:0)

使用导航控制器,您可以创建类似的Objective-C类别,并在子视图控制器中使用它们

#import "UINavigationController+Orientation.h"

@implementation UINavigationController (Orientation)

- (NSUInteger)supportedInterfaceOrientations {
    return [self.topViewController supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotate {
    return YES;
}

@end

对于Swift

extension UINavigationController {

    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return topViewController?.supportedInterfaceOrientations ?? .portrait
    }

    open override var shouldAutorotate: Bool {
        return true
    }

}