播放器页
同样,先创建代表播放器页的VedioPlayer:
import SwiftUI
struct VedioPlayer {}
Content View
我们的播放器是PlayerViewController,要在SwiftUI中使用,只需要一个类或结构体,实现协议UIViewControllerRepresentable即可,核心方法:
- makeUIViewController,返回要展示的UIViewController对象,这里是我们的PlayerViewController(),设置好视频地址和标题即可,presentation.wrappedValue.dismiss()表示popViewController()
- updateUIViewController,是在状态发生改变时,SwiftUI通知UIKit的方式,我们播放器相关的所有逻辑都在PlayerViewController里面,所以是空的
代码如下:
extension VedioPlayer {
struct Content: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentation
let url: String
let title: String
func makeUIViewController(context: UIViewControllerRepresentableContext<Content>) -> PlayerViewController {
let vc = PlayerViewController()
vc.prepareFor(url: url, title: title)
vc.tapBackHandler = {
self.presentation.wrappedValue.dismiss()
}
return vc
}
func updateUIViewController(_ uiViewController: PlayerViewController, context: UIViewControllerRepresentableContext<Content>) {
}
}
}
Container View
Container视图的工作就是根据传入的VedioManager.File,配置Content view的视频地址和标题,注意这里也有个坑,SwiftUI中想让导航条隐藏,必须要设置标题。。
代码如下:
extension VedioPlayer {
struct Container: View {
let file: VedioManager.File
var body: some View {
/// For some reason, SwiftUI requires that you also set .navigationBarTitle for .navigationBarHidden to work properly.
Content(url: file.path, title: file.name)
.edgesIgnoringSafeArea(.all)
.navigationBarTitle(Text(file.name), displayMode: .inline)
.navigationBarHidden(true)
.onDisappear { print("onDisappear") }
}
}
}
Root View
最后就是我们的root View,NavigationView就是UINavigationController了:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VedioList.Container(path: VedioManager.root)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}