You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现AVPlayerLayer在全iOS设备上全屏显示?

Fix Video Fullscreen Display Across All iOS Devices

Hey there! Let's get that video playing fullscreen on every device—no more weird sizing issues on iPhone 8 Plus or other models. The core problem with your current setup is that you're setting a fixed frame for the AVPlayerLayer once (in viewDidLoad), which doesn't account for different screen sizes or layout changes. Here's how to fix it step by step:

Step 1: Verify Your UIView Constraints

First, double-check the constraints for your videoUiViewOutlet (the UIView you added to hold the video):

  • Make sure it has leading, trailing, top, and bottom constraints pinned directly to its parent view (the view controller's main view). This ensures the container view stretches to fill the entire screen on any device.
  • If you haven't set these yet, select the UIView in Interface Builder, use the "Pin" tool to add all four edge constraints with 0 spacing.

Step 2: Update Your Code to Handle Dynamic Layouts

We need to make the AVPlayerLayer resize automatically when its container view changes size. Here's the revised code with key fixes:

import UIKit
import AVFoundation
import AVKit

class TestViewController: UIViewController {
    private var player: AVPlayer!
    // Make playerLayer an instance variable so we can update it later
    private var playerLayer: AVPlayerLayer!
    @IBOutlet weak var videoUiViewOutlet: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupView()
    }

    private func setupView() {
        guard let videoPath = Bundle.main.path(forResource: "clouds", ofType: "mp4"),
              let videoUrl = URL(fileURLWithPath: videoPath) else {
            print("Failed to load video file")
            return
        }
        
        let player = AVPlayer(url: videoUrl)
        self.player = player
        
        // Initialize playerLayer and configure it
        playerLayer = AVPlayerLayer(player: player)
        playerLayer.videoGravity = .resizeAspectFill // Ensures video fills the layer without distortion
        videoUiViewOutlet.layer.addSublayer(playerLayer)
        
        player.play()
        player.actionAtItemEnd = .none

        // Add notification observers
        NotificationCenter.default.addObserver(self, selector: #selector(videoDidPlayToEnd(notification:)), name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
        NotificationCenter.default.addObserver(self, selector: #selector(enteredBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(enteredForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
    }

    // Override layoutSubviews to update the playerLayer's frame whenever the view resizes
    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer?.frame = videoUiViewOutlet.bounds
    }

    @objc func videoDidPlayToEnd(notification: Notification) {
        guard let playerItem = notification.object as? AVPlayerItem else { return }
        playerItem.seek(to: .zero, completionHandler: nil)
    }

    @objc func enteredBackground() {
        player.pause()
    }

    @objc func enteredForeground() {
        player.play()
    }

    // Clean up observers to avoid memory leaks
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

Key Fixes Explained:

  • Instance Variable for playerLayer: By storing the player layer as an instance variable, we can access it later to update its frame when the view resizes.
  • layoutSubviews Override: This method gets called every time the view's size changes (like when rotating the device or running on a different screen size). We update the player layer's frame to match the container view's bounds here, ensuring it always fills the container.
  • Safer Video URL Loading: Added optional binding to handle cases where the video file might be missing, preventing crashes.
  • Memory Leak Prevention: Added a deinit method to remove all notification observers, which is good practice to avoid memory leaks.

Bonus: Handle Screen Rotation (Optional)

If you want to support screen rotation, make sure your view controller allows it:

  • In your project settings, go to the "General" tab, under "Deployment Info", check all the device orientations you want to support.
  • The layoutSubviews method will automatically handle resizing the video layer when the screen rotates, so no extra code is needed for that!

After making these changes, your video should fill the screen perfectly on every iOS device, including iPhone 8 Plus.

内容的提问来源于stack exchange,提问作者mannyCalavera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:38:27