Как создать приложение, используя шаблон приложения Single View, в котором главное окно не вращается, а все остальное вращается?

Как создать приложение, используя шаблон приложения Single View App, в котором главное окно не вращается, а его rootViewController и все остальное автоматически поворачивается?

Apple делает это на CIFunHouse, но поскольку код плохо объясняется в этом вопросе, невозможно знать, как они это сделали. Если вы запустите приложение, вы увидите, что окно предварительного просмотра камеры не будет автоматически, потому что предварительный просмотр был добавлен в окно, но все остальное делает.

Apple использует эту технику в своем родном приложении для камеры iPad.

2 ответа

Решение

Так что ответ не чистый, но я могу дать вам исправление. В какой-то момент главное окно приложения не должно было автоматически поворачиваться, как сейчас, но в какой-то момент оно начало вращаться в соответствии с 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

Затем в viewDidLoad FHViewController вместо добавления в главное окно я сделал это, и он добавил, где они получают главное окно, и я добавил в него 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

Для iPad требуется полноэкранный режим, необходимо проверить.

С помощью контроллера навигации вы можете создать категорию Objective-C, например, и использовать ее в субконтроллерах

#import "UINavigationController+Orientation.h"

@implementation UINavigationController (Orientation)

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

- (BOOL)shouldAutorotate {
    return YES;
}

@end

Для Свифта

extension UINavigationController {

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

    open override var shouldAutorotate: Bool {
        return true
    }

}
Другие вопросы по тегам