Ios AirPlay至苹果电视全屏

Ios AirPlay至苹果电视全屏,ios,airplay,apple-tv,Ios,Airplay,Apple Tv,目前,我为iPhone/iPad制作的任何应用程序都可以通过AirPlay镜像到苹果电视上。然而,即使在横向模式下,它也只占据屏幕的中心部分,左右两侧都是黑色。以Real Racing HD等应用程序的方式,将其全屏播放到AirPlay涉及到什么 编辑:根据建议,我已经添加了我正在使用的所有代码,我没有告诉secondWindow使用与正常相同的根视图控制器,而是设置了一个不同颜色的新VC,以查看是否正确设置了机制。它们不是,因为它仍然只是进行正常镜像,即使在告诉它使用不同的VC时也是如此 这里

目前,我为iPhone/iPad制作的任何应用程序都可以通过AirPlay镜像到苹果电视上。然而,即使在横向模式下,它也只占据屏幕的中心部分,左右两侧都是黑色。以Real Racing HD等应用程序的方式,将其全屏播放到AirPlay涉及到什么

编辑:根据建议,我已经添加了我正在使用的所有代码,我没有告诉secondWindow使用与正常相同的根视图控制器,而是设置了一个不同颜色的新VC,以查看是否正确设置了机制。它们不是,因为它仍然只是进行正常镜像,即使在告诉它使用不同的VC时也是如此

这里是AppDelegate.h

#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];
}