我几天前创建了一个问题,并提供了有关如何解决来回传递数据问题的协议。我也看了一些教程,并创建了一个协议,但它没有工作,甚至从我看到它应该工作的断点。我已经为我的AVPlayer创建了一个协议,以便点击它可以获得一个新的视频,但就像我说它甚至没有达到断点这是我的代码...
protocol CustomAVPLayerProtocol: class {
func reloadTabled(at index: Int)
}
class CustomAVPLayerC: AVPlayerViewController {
var delagate: CustomAVPLayerProtocol?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.delagate?.reloadTabled(at: 1)
for touch in touches {
self.delagate?.reloadTabled(at: 1)
print("Tapped")
// When I tap the AVPlayer this print statement shows
// So I know it is coming here
}
}
}
现在这是我的第二个类/控制器
class BookViewC: UIViewController, CustomAVPLayerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
PlayVideo(250, "url")
}
func reloadTabled(at index: Int) {
print("This protocol method does not execute or hit breakpoint")
self.PlayVideo(250, "url")
}
func PlayVideo(MediaHeight: Float, MediaURL: String) {
let movieURL = URL(string: MediaURL)
videoCapHeight.constant = CGFloat(MediaHeight)
streamsModel.playerView = AVPlayer(url: movieURL!)
streamsModel.MyAVPlayer.player = streamsModel.playerView
streamsModel.MyAVPlayer.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
streamsModel.MyAVPlayer.showsPlaybackControls = false
streamsModel.MyAVPlayer.view.frame = VideoView.bounds
VideoView.addSubview(streamsModel.MyAVPlayer.view)
self.addChildViewController(streamsModel.MyAVPlayer)
streamsModel.playerView?.isMuted = false
streamsModel.MyAVPlayer.player?.play()
}
}
正如我之前所述,它甚至没有点击 BookViewC.reloadTabled上的断点,因为建议会很棒
答案 0 :(得分:2)
根据您的代码,这些是一些小错误,您可以纠正这些错误以使其正常工作。
1. `weak var delagate: CustomAVPLayerProtocol?`
*Make a weak delegate to save it from retaining a strong reference cycle and memory leaks.*
2. Code Snippet:
func PlayVideo {
let customPlayer = CustomAVPLayerC()
customPlayer.delegate = self
}
你的第二个ViewController中的,你需要将你的委托分配给一个对象/视图控制器来做出响应
注意:如果需要,您可以创建一个符合您的协议类的超类,以便您的每个视图控制器自动符合它,您只需要将一个委托分配给您要使用它的类。
答案 1 :(得分:1)
协议是无关对象用于彼此通信的最常用方法。根据上面的代码,通信似乎没有发生。
您的协议声明部分似乎没问题。第二个ViewController中存在问题。我可以看到你没有将委托设置为已创建的对象。理想情况下,它必须是这样的:
Class BookViewC: UIViewController, CustomAVPLayerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
PlayVideo(250, "url")
}
您需要在此处设置委托:
func PlayVideo {
let customPlayer = CustomAVPLayerC()
customPlayer.delegate = self //This makes the selector to respond
}
答案 2 :(得分:1)
代理只处理实例(尽管你可以操作事物,以便你可以“委托”到类型,或者至少表面上)。您已正确设置基础,但请记住,这两个类只是运行它们的实例的蓝图。在创建这些类的实例之前,类(和所有类型)本身不会执行任何操作。这是完成所有工作的实例。
因此,只需将一个实例作为另一个实例的委托传递,您可以在此处执行,因为您已正确设置协议。
protocol CustomAVPLayerProtocol: AnyObject {
func reloadTabled(at index: Int)
}
class CustomAVPLayerC: AVPlayerViewController {
weak var delagate: CustomAVPLayerProtocol?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.delagate?.reloadTabled(at: 1)
for touch in touches {
self.delagate?.reloadTabled(at: 1)
print("Tapped")
}
}
}
class BookViewC: UIViewController, CustomAVPLayerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
PlayVideo(250, "url")
}
func reloadTabled(at index: Int) {
PlayVideo(250, "url")
}
func PlayVideo(_ MediaHeight: Float, _ MediaURL: String) {
//
}
}
let book = BookViewC()
let layer = CustomAVPLayerC()
layer.delagate = book
您执行此操作的实例化/委派取决于您以及您希望如何构建程序。
此外,我知道很多人使用class
来定义仅符合类的协议,但Swift的文档指示我们使用AnyObject
来定义仅类协议。