我有一个 iOS 应用程序,当它通过 Airplay 镜像到 Apple TV 时,它实际上占据了整个电视屏幕,就好像 UIKit 正在读取电视的实际尺寸一样。然而,这不是我想要的 - 我只想镜像应用程序以适应电视屏幕(像大多数其他应用程序一样)并显示黑色区域。我该怎么做?
编辑:澄清一下,我只想按原样镜像屏幕,而不是尝试显示任何其他内容。
编辑2:
我在 App/SceneDelegate 中做的唯一一件事是以编程方式设置委托类(因为我不想在 plist 中设置它):
在我的应用程序委托中:
public func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Since we manually create the config instead of reading "DefaultConfiguration" from Info.Plist, we should delete the entry in info.plist.
let config = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
config.delegateClass = Self.self
config.sceneClass = UIWindowScene.self
return config
}
在我的场景中代表:
public func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = rootVC()
window.makeKeyAndVisible()
window.overrideUserInterfaceStyle = .light
}
然后我的 plist 的“应用程序场景清单”删除了类设置:
在代码中的某个时刻,您正在设置用于外部显示器的窗口。这里您需要使用设备的大小创建一个窗口。
您可以使用主屏幕的框架实例化窗口,如下所示:
window = UIWindow(frame: UIScreen.main.bounds)
终于找到问题了。这是因为当使用airplay时,
willConnectTo
会再次被session.role == .windowExternalDisplayNonInteractive
调用。我们需要检查session.role
,并在这种情况下提前返回:
public func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// willConnectTo is called again when connect to an external display (airplay), with a different role type.
// If we don't do anything, iOS will simply mirror the screen.
guard session.role == .windowApplication else {
return
}
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = rootVC()
window.makeKeyAndVisible()
window.overrideUserInterfaceStyle = .light
}
要实现将 iOS 应用程序镜像到具有黑色区域的 Apple TV 屏幕而不是占据整个屏幕的所需行为,您可以按照以下步骤操作:
确定 Apple TV 的屏幕分辨率。大多数 Apple TV 的默认分辨率为 1920x1080 像素,即长宽比为 16:9。不过,以编程方式获取实际屏幕尺寸以考虑不同 Apple TV 型号或未来潜在更新的差异始终是一个好习惯。
修改 iOS 应用程序的视图层次结构以匹配 Apple TV 屏幕的宽高比。一种方法是将应用程序的内容嵌入到保持所需宽高比(在本例中为 16:9)的容器视图中。您可以在内容视图周围添加黑色区域(具有黑色背景颜色的 UIView)以填充剩余空间。
以下是如何以编程方式执行此操作的示例:
class ViewController: UIViewController {
// Container view to maintain the aspect ratio of the Apple TV screen
let containerView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
// Set up the container view
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.backgroundColor = .black
// Add the container view to the main view
view.addSubview(containerView)
// Configure constraints to maintain aspect ratio and fill the screen
NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
containerView.topAnchor.constraint(equalTo: view.topAnchor),
containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
// Add your app's content view to the container view
let contentView = UIView()
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = .red // Replace with your actual content view
containerView.addSubview(contentView)
// Configure constraints for the content view
NSLayoutConstraint.activate([
contentView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
contentView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
contentView.widthAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 16.0 / 9.0) // Aspect ratio of 16:9
])
}
}
通过将应用程序的内容嵌入到容器视图中,您可以确保它在 Apple TV 屏幕上保持所需的宽高比。黑色区域填充剩余空间,为您的应用程序的内容提供宽高比匹配的效果。