这是 SwiftUI 中视频播放器的示例代码片段,其中播放器的核心是在 UIKit 中实现的(具体在
PlayerViewController
中):
struct Page: View {
let delegate = Delegate()
@State private var isPlay = true
var body: some View {
VStack {
PlayerView(delegate: delegate)
Button("Play") { delegate.play() }
}
}
}
class Delegate {
var controller: PlayerViewController? = nil
func play() { controller?.play() }
func pause() { controller?.pause() }
}
struct PlayerView: UIViewControllerRepresentable {
let delegate: Delegate
func makeUIViewController(context: Context) -> some UIViewController {
let c = PlayerViewController()
delegate.controller = c
return c
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
}
class PlayerViewController: UIViewController {
func play() { ... }
func pause() { ... }
}
在上面的代码中,页面正确显示
PlayerViewController
,并且视频播放没有问题。但是,当我尝试在视频上调用 play
或 pause
等函数时,我遇到了问题。
我创建了一个委托(
Delegate
类)来封装这些函数,将委托传递给PlayerView
,并在delegate.controller = c
方法中分配makeUIViewController
。
不幸的是,当我点击播放按钮时,我发现
controller
为零。
我很困惑为什么这个代表没有按预期运作。谁能帮助我了解出了什么问题,并指导我如何解决它?任何帮助将不胜感激!
此外,我在操场上复制了相同的场景,一切似乎都按预期进行:
class City {
let name: String
init(name: String) { self.name = name }
func say() { print("hello I am \(name)") }
}
class Delegate {
var city: City? = nil
func sayFromDelegate() {
city?.say()
}
}
struct Person {
let name: String = "Person"
let delegate: Delegate
func foo() {
let c = City(name: "QingDao")
delegate.city = c
}
}
let d = Delegate()
let p = Person(delegate: d)
p.foo() // force bind delegate
d.sayFromDelegate() // hello I am QingDao
视图结构是短暂的,因此无法保留对象,因此您的
let delegate = Delgate()
是内存泄漏。
如果这些值自上次调用 update 以来发生了变化,您需要将闭包或绑定传递给 UIViewControllerRepresentable 并实现更新函数来更新视图控制器。