如何使用主 window 不旋转但其余部分旋转的单视图应用程序模板创建应用程序?
How to create an App using the Single View App template where the main window does not rotate but the rest does?
如何使用主 window 不旋转但其 rootViewController 和其他所有内容自动旋转的单视图应用程序模板创建应用程序?
Apple 在 CIFunHouse 上这样做了,但由于代码在这方面的解释很差,因此不可能知道他们是如何做到的。如果您 运行 该应用程序,您会看到相机的预览 window 不会自动旋转,因为预览已添加到 window 但其他所有内容都会自动旋转。
Apple 在其原生 iPad 相机应用程序中使用了此技术。
通过使用导航控制器,您可以创建一个 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
}
}
所以答案不是很清楚,但我可以给你一个修复。在某些时候,主应用程序 window 不能像现在这样自动旋转,但在某些时候它开始根据 rootviewcontroller 旋转。至少这个源代码表明了这一点。我在 iOS 6 年底开始开发,我认为这个资源是在那个时候写的。我能找到的允许示例中的所有内容旋转但预览不旋转的最佳修复是添加第二个 window。将主要 window 背景设置为清除。然后将 previewLayer 添加到主要 window 后面的第二个 window。在代码中它看起来像这样。
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 中而不是添加到主视图中 window 我这样做并添加了他们获得主视图的地方 window 我将 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.
为我工作
编辑:上面示例中的视图不旋转,但旋转时的 window 动画在视觉上很糟糕。它可以通过重写来删除
willTransitionToSize
[UIView setAnimationsEnabled:NO];
完成后
[UIView setAnimationsEnabled:YES];
参见 GitHub
上的 swift 版本
对于 iPad 要求必须选中全屏。
如何使用主 window 不旋转但其 rootViewController 和其他所有内容自动旋转的单视图应用程序模板创建应用程序?
Apple 在 CIFunHouse 上这样做了,但由于代码在这方面的解释很差,因此不可能知道他们是如何做到的。如果您 运行 该应用程序,您会看到相机的预览 window 不会自动旋转,因为预览已添加到 window 但其他所有内容都会自动旋转。
Apple 在其原生 iPad 相机应用程序中使用了此技术。
通过使用导航控制器,您可以创建一个 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
}
}
所以答案不是很清楚,但我可以给你一个修复。在某些时候,主应用程序 window 不能像现在这样自动旋转,但在某些时候它开始根据 rootviewcontroller 旋转。至少这个源代码表明了这一点。我在 iOS 6 年底开始开发,我认为这个资源是在那个时候写的。我能找到的允许示例中的所有内容旋转但预览不旋转的最佳修复是添加第二个 window。将主要 window 背景设置为清除。然后将 previewLayer 添加到主要 window 后面的第二个 window。在代码中它看起来像这样。
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 中而不是添加到主视图中 window 我这样做并添加了他们获得主视图的地方 window 我将 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.
为我工作编辑:上面示例中的视图不旋转,但旋转时的 window 动画在视觉上很糟糕。它可以通过重写来删除 willTransitionToSize
[UIView setAnimationsEnabled:NO];
完成后
[UIView setAnimationsEnabled:YES];
参见 GitHub
上的 swift 版本对于 iPad 要求必须选中全屏。