如何在UIPageViewController后方添加固定循环背景视频视图?
解决方案:实现固定循环视频背景 + 透明横向滚动页面
嘿,我来帮你搞定这个问题!核心思路很简单:把视频背景牢牢放在视图层级的最底部,让你的横向滚动页面容器(不管是UIPageViewController还是UIScrollView)叠加在它上方,同时确保滚动页面的背景全透明,这样就能透过页面看到底层循环播放的视频了。
1. 先做一个可复用的视频背景视图类
先封装一个专门的VideoBackgroundView,把视频播放、循环、适配的逻辑都塞进去,后续用起来更方便:
import UIKit import AVFoundation class VideoBackgroundView: UIView { private var player: AVPlayer? private var playerLayer: AVPlayerLayer? // 初始化时传入本地视频文件名(比如你的视频叫login_bg.mp4,就传"login_bg") init(videoName: String, videoType: String = "mp4") { super.init(frame: .zero) setupVideoPlayer(videoName: videoName, videoType: videoType) } required init?(coder: NSCoder) { super.init(coder: coder) // 如果是从Storyboard拖的视图,这里可以补默认视频的初始化逻辑 } private func setupVideoPlayer(videoName: String, videoType: String) { guard let videoURL = Bundle.main.url(forResource: videoName, withExtension: videoType) else { print("找不到目标视频文件,请检查文件名和路径") return } player = AVPlayer(url: videoURL) player?.actionAtItemEnd = .none // 播放结束后不自动暂停 playerLayer = AVPlayerLayer(player: player) playerLayer?.frame = bounds playerLayer?.videoGravity = .resizeAspectFill // 保持视频比例,填满整个视图 playerLayer?.masksToBounds = true if let layer = playerLayer { layer.insertSublayer(layer, at: 0) // 强制把视频层放在最底层 } // 监听播放结束事件,实现循环播放 NotificationCenter.default.addObserver( self, selector: #selector(restartVideo), name: .AVPlayerItemDidPlayToEndTime, object: player?.currentItem ) player?.play() } @objc private func restartVideo() { player?.seek(to: .zero) player?.play() } // 适配视图尺寸变化(比如旋转屏幕) override func layoutSubviews() { super.layoutSubviews() playerLayer?.frame = bounds } // 销毁时清理资源,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) player?.pause() player = nil } }
2. 在BootViewController中整合视频背景
假设你已经有了处理横向滚动的容器(比如pageViewController或者scrollView),现在把视频背景加进去:
方式一:纯代码实现
在viewDidLoad里添加以下逻辑:
override func viewDidLoad() { super.viewDidLoad() // 1. 创建视频背景视图,插入到当前控制器view的最底层 let videoBgView = VideoBackgroundView(videoName: "login_bg") videoBgView.translatesAutoresizingMaskIntoConstraints = false view.insertSubview(videoBgView, at: 0) // 2. 约束视频背景铺满整个屏幕 NSLayoutConstraint.activate([ videoBgView.topAnchor.constraint(equalTo: view.topAnchor), videoBgView.leadingAnchor.constraint(equalTo: view.leadingAnchor), videoBgView.trailingAnchor.constraint(equalTo: view.trailingAnchor), videoBgView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) // 3. 让滚动容器的背景透明 if let pageContainerView = pageViewController?.view { pageContainerView.backgroundColor = .clear } // 4. 重点!每个滚动页面的ViewController的view也要设为透明 // 比如在每个页面的viewDidLoad里加:view.backgroundColor = .clear }
方式二:结合Storyboard操作
如果你的BootViewController是在Storyboard里做的:
- 给BootViewController的view拖一个普通UIView,设置约束为铺满全屏,然后在Document Outline里把这个View拖到最底部(确保层级最低)
- 给这个View设置自定义类为
VideoBackgroundView - 打开User Defined Runtime Attributes,添加
videoName(String类型),值填你的视频文件名 - 找到你的滚动容器(比如UIPageViewController的view),在Attributes Inspector里把背景色设为
Clear Color - 最后给每个滚动页面的ViewController的view也设置背景色为
Clear Color
3. 关键注意事项
- 视频格式检查:确保你的视频是iOS支持的格式(推荐mp4+H.264编码),并且已经正确添加到项目中(勾选了对应的target)
- 性能优化:如果视频体积太大,建议压缩到合适分辨率;可以在控制器进入后台时暂停视频,回到前台再继续播放
- 层级验证:用Xcode的Debug View Hierarchy功能查看视图层级,确认视频背景在最底层,滚动页面在上方且透明
- 静音处理:如果不需要视频声音,可以在
setupVideoPlayer里加player?.isMuted = true
这样设置完,你的横向滚动页面就能在固定循环的视频背景上滑动,最后一页的登录表单也能正常显示在视频之上啦!
内容的提问来源于stack exchange,提问作者Perdona
相关产品推荐
相关产品推荐

