Ios AirPlay至苹果电视全屏
目前,我为iPhone/iPad制作的任何应用程序都可以通过AirPlay镜像到苹果电视上。然而,即使在横向模式下,它也只占据屏幕的中心部分,左右两侧都是黑色。以Real Racing HD等应用程序的方式,将其全屏播放到AirPlay涉及到什么 编辑:根据建议,我已经添加了我正在使用的所有代码,我没有告诉secondWindow使用与正常相同的根视图控制器,而是设置了一个不同颜色的新VC,以查看是否正确设置了机制。它们不是,因为它仍然只是进行正常镜像,即使在告诉它使用不同的VC时也是如此 这里是AppDelegate.hIos AirPlay至苹果电视全屏,ios,airplay,apple-tv,Ios,Airplay,Apple Tv,目前,我为iPhone/iPad制作的任何应用程序都可以通过AirPlay镜像到苹果电视上。然而,即使在横向模式下,它也只占据屏幕的中心部分,左右两侧都是黑色。以Real Racing HD等应用程序的方式,将其全屏播放到AirPlay涉及到什么 编辑:根据建议,我已经添加了我正在使用的所有代码,我没有告诉secondWindow使用与正常相同的根视图控制器,而是设置了一个不同颜色的新VC,以查看是否正确设置了机制。它们不是,因为它仍然只是进行正常镜像,即使在告诉它使用不同的VC时也是如此 这里
#import <UIKit/UIKit.h>
@class MainView;
@class ViewController;
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *tabBarController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *tabBarController;
@property (nonatomic, retain) UIWindow *secondWindow;
@end
让它在AirPlay全屏播放所涉及的一切
如果您想深入了解,请从这里开始了解iOS世界中的Windows和屏幕:
如果您想先进行更广泛的概述,这里是包含视频和其他教程/文档的聚合页面:
[编辑]这是我的一个应用程序的代码摘录,我正在设置第二个显示器。我从我给你的链接中获取了很多信息。注:“主”是设备的“远程”是电视的“远程”
注:此代码不完整;仍然存在它不响应的状态更改。运行此操作之前,请连接到AirPlay接收器并打开镜像
我有这个:
@interface AppDelegate () {
SFCManagerMainViewController *_mainVC;
SFCRemoteMonitorViewController *_remoteVC;
}
@end
标题:
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIWindow *secondWindow;
这是:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[self setUpScreenConnectionNotificationHandlers];
[self checkForExistingScreenAndInitializeIfPresent];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_mainVC = [[SFCManagerMainViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = _mainVC;
[self.window makeKeyAndVisible];
return YES;
}
- (void)checkForExistingScreenAndInitializeIfPresent {
if ([[UIScreen screens] count] > 1) {
// Get the screen object that represents the external display.
UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
// Get the screen's bounds so that you can create a window of the correct size.
CGRect screenBounds = secondScreen.bounds;
self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
self.secondWindow.screen = secondScreen;
// Set up initial content to display...
NSLog(@"Setting up second screen: %@", secondScreen);
_remoteVC = [[SFCRemoteMonitorViewController alloc] initWithNibName:nil bundle:nil];
self.secondWindow.rootViewController = _remoteVC;
[self.secondWindow makeKeyAndVisible];
// Show the window.
self.secondWindow.hidden = NO;
}
}
- (void)setUpScreenConnectionNotificationHandlers {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(handleScreenDidConnectNotification:)
name:UIScreenDidConnectNotification object:nil];
[center addObserver:self selector:@selector(handleScreenDidDisconnectNotification:)
name:UIScreenDidDisconnectNotification object:nil];
}
- (void)handleScreenDidConnectNotification:(NSNotification*)aNotification {
UIScreen *newScreen = [aNotification object];
CGRect screenBounds = newScreen.bounds;
if (!self.secondWindow) {
NSLog(@"Initializing secondWindow/screen in notification");
self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
self.secondWindow.screen = newScreen;
// Set the initial UI for the window.
_remoteVC = [[SFCRemoteMonitorViewController alloc] initWithNibName:nil bundle:nil];
self.secondWindow.rootViewController = _remoteVC;
} else {
NSLog(@"Second window already initialized.");
}
}
- (void)handleScreenDidDisconnectNotification:(NSNotification*)aNotification {
if (self.secondWindow) {
// Hide and then delete the window.
self.secondWindow.hidden = YES;
self.secondWindow = nil;
}
}
首先,电视本身是否有可能覆盖某些过扫描设置 您可能想查看一些有关
UIScreen
的API,具体如下:
@property(nonatomic) UIScreenOverscanCompensation overscanCompensation
@property(nonatomic,retain) UIScreenMode *currentMode
@property(nonatomic,readonly,copy) NSArray *availableModes
否则,另一个选项是禁用镜像,并将图形绘制到屏幕大小的视图中:
//Be sure to check for the screen's existence first :)
UIScreen *secondScreen = [UIScreen screens][1];
//Create a window that is the size of the second screen
self.externalWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, secondScreen.bounds.size.width, secondScreen.bounds.size.height)];
//Set to a view controller that should be displayed
self.externalWindow.rootViewController = [[MyViewController alloc] init];
//Move the new window to the second screen
self.externalWindow.screen = secondScreen;
self.externalWindow.hidden = NO;
您只需设置过扫描补偿:
UIScreen* secondScreen = (...);
secondScreen.overscanCompensation = UIScreenOverscanCompensationInsetApplicationFrame;
如果您想要完整的代码来测试它,只需将以下代码放在AppDelegate.m
和应用程序中的某个地方:didFinishLaunchingWithOptions:
调用[self-setupAirplay]代码>
-(void)setupAirplay{
// self.windows is a NSMutableArray property on AppDelegate
self.windows = [[NSMutableArray alloc] init];
NSArray* screens = [UIScreen screens];
for (UIScreen *_screen in screens){
if (_screen == [UIScreen mainScreen])
continue;
NSNotification* notification = [[NSNotification alloc] initWithName:UIScreenDidConnectNotification object:_screen userInfo:nil];
[self screenDidConnect:notification];
}
// Register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(screenDidConnect:)
name:UIScreenDidConnectNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(screenDidDisconnect:)
name:UIScreenDidDisconnectNotification
object:nil];
}
- (UIWindow *) createWindowForScreen:(UIScreen *)screen {
UIWindow *aWindow = nil;
// Do we already have a window for this screen?
for (UIWindow *window in self.windows){
if (window.screen == screen){
aWindow = window;
}
}
// Still nil? Create a new one.
if (aWindow == nil){
aWindow = [[UIWindow alloc] initWithFrame:[screen bounds]];
[aWindow setScreen:screen];
[self.windows addObject:aWindow];
}
return aWindow;
}
- (void) screenDidConnect:(NSNotification *) notification {
UIScreen* screen = [notification object];
NSLog(@"Screen connected: %.0f x %.0f", screen.bounds.size.width, screen.bounds.size.height);
// Create a view controller for the new window (you should use a Storyboard / XIB)
UIViewController* airplay = [[UIViewController alloc] init];
airplay.view = [[UIView alloc] initWithFrame:screen.bounds];
[airplay.view setBackgroundColor:[UIColor whiteColor]];
UILabel* label = [[UILabel alloc] initWithFrame:screen.bounds];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont systemFontOfSize:40.0f]];
[label setText:@"AirPlay Screen"];
[airplay.view addSubview:label];
// Comment this line and you'll get the four black borders:
screen.overscanCompensation = UIScreenOverscanCompensationInsetApplicationFrame;
UIWindow* aWindow = [self createWindowForScreen:screen];
// Add the view controller to the window
[aWindow setRootViewController:airplay];
[aWindow setHidden:NO];
}
- (void) screenDidDisconnect:(NSNotification *) notification {
NSLog(@"Screen disconnected");
UIScreen* screen = [notification object];
// Find any window attached to this screen, remove it from our window list
for (UIWindow *oneWindow in self.windows){
if (oneWindow.screen == screen){
NSUInteger windowIndex = [self.windows indexOfObject:oneWindow];
[self.windows removeObjectAtIndex:windowIndex];
}
}
return;
}
在使用iPadMini2进行测试时,我的第三代苹果电视并没有获得1080p的分辨率,但我获得了720p的全屏幕分辨率。我不确定这是否是整个AirPlay概念所期望的,或者这里的速度不够快,但我希望我能得到1080p
如果您在设置AirPlay方面需要任何进一步的帮助,请告诉我,但它应该可以按原样工作。这对我来说适用于使用iPad Air的新旧苹果电视。
第二个窗口在电视上全屏显示,而您的普通用户界面在iPad上显示
在AppDelegate.m中插入:
@property UIWindow *secondWindow;
源代码:操作系统必须认为您的应用程序仍处于纵向模式。@StileScriss否,这是任何应用程序的行为,无论处于横向模式,它都将显示居中的缩放视图。我知道可以让它在苹果电视上全屏显示,只是不知道如何。这可以在AirPlay设备上添加不同的视图,但我只是想在苹果电视上镜像我的应用程序。如果我不添加任何代码,它会镜像到苹果电视上,但左右两侧都有条。如果我添加代码,我会得到一个空白屏幕。哦,我明白了。您是否尝试在主屏幕上设置过扫描补偿?(我现在不在家,所以我无法检查)如果我不添加任何代码,它会镜像到苹果电视上,但左右两侧都有条带。如果我添加代码,我会得到一个空白屏幕。我完全按照第一个链接的指示,在我的苹果电视上得到了一个空白屏幕。这是我期望的一部分。在第一个链接中,您将获得一个额外的屏幕(类似于第二个监视器,而不是现有监视器的副本),您可以在该屏幕上放置可以调整为全宽/全高的内容。如果您的界面使用大小类/自动布局,您应该能够将视图控制器添加到第二个屏幕,并看到更多您期望的内容。好的,按照Apple的说明,添加链接中列出的代码,然后如何将iPad屏幕上的内容复制到第二个屏幕上?请看我为包含代码而进行的编辑回答。好的,如果我想准确镜像显示,那么我在didfishLaunching
中的主屏幕看起来像[window setRootViewController:tabBarController]
那么我是否应该能够生成另一个代码[self.secondWindow.rootViewController=tabBarController]代码>?我试过了,在苹果电视上得到了空白屏幕。
@property UIWindow *secondWindow;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([UIScreen screens].count > 1) {
[self setUpSecondWindowForScreen:[UIScreen screens][1]];
}
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(handleScreenDidConnectNotification:)
name:UIScreenDidConnectNotification object:nil];
[center addObserver:self selector:@selector(handleScreenDidDisconnectNotification:)
name:UIScreenDidDisconnectNotification object:nil];
return YES;
}
- (void)handleScreenDidConnectNotification:(NSNotification*)notification {
if (!self.secondWindow) {
[self setUpSecondWindowForScreen:[notification object]];
}
}
- (void)handleScreenDidDisconnectNotification:(NSNotification*)notification {
if (self.secondWindow) {
self.secondWindow = nil;
}
}
- (void)setUpSecondWindowForScreen:(UIScreen*)screen {
self.secondWindow = [[UIWindow alloc] init];
self.secondWindow.screen = screen;
self.secondWindow.screen.overscanCompensation = UIScreenOverscanCompensationNone;
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
self.secondWindow.rootViewController = viewController;
[self.secondWindow makeKeyAndVisible];
}