为什么 SwiftUI 中不使用 UIViewControllerRepresentable 委托工作?

问题描述 投票:0回答:1

这是 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
swift swiftui delegates automatic-ref-counting
1个回答
0
投票

视图结构是短暂的,因此无法保留对象,因此您的

let delegate = Delgate()
是内存泄漏。

如果这些值自上次调用 update 以来发生了变化,您需要将闭包或绑定传递给 UIViewControllerRepresentable 并实现更新函数来更新视图控制器。

© www.soinside.com 2019 - 2024. All rights reserved.