如何从Xib视图跳转至Storyboard控制器?解决Delegate为空问题
问题分析与修复方案
问题1:Delegate始终为空的原因及修复
你在YoutubeVideoViewController中新建了一个BookDetailVideoViewController实例myDelegate并设置delegate,但这个实例并非界面上实际显示的Xib视图控制器。实际展示的BookDetailVideoViewController是在其他地方创建的,必须在那个创建实例的位置设置delegate才有效。
修复步骤:
- 找到创建并展示
BookDetailVideoViewController的代码(通常在父视图控制器中),在那里绑定delegate:
// 示例:在父VC中创建并配置Xib视图控制器 let videoVC = BookDetailVideoViewController(nibName: "BookDetailVideoViewController", bundle: nil) videoVC.delegate = self // 父VC需遵守BookDetailVideoViewDelegate协议 videoVC.initializeView(url: targetURL, index: targetIndex, book: targetBook) // 若添加为子视图: self.view.addSubview(videoVC.view) videoVC.didMove(toParent: self) // 若推入导航栈: self.navigationController?.pushViewController(videoVC, animated: true)
- 删除
YoutubeVideoViewController中的无效代码:
// 删除这两行 let myDelegate : BookDetailVideoViewController = BookDetailVideoViewController() myDelegate.delegate = self
问题2:跳转失败的原因及修复
当前videoOpen方法写在目标跳转VC(YoutubeVideoViewController)中,逻辑完全错误——跳转目标不应作为delegate回调的接收者。正确逻辑是:让创建Xib视图控制器的父VC遵守协议,通过回调触发跳转操作。
修复步骤:
- 让父视图控制器实现
BookDetailVideoViewDelegate协议:
class ParentViewController: UIViewController, BookDetailVideoViewDelegate { // 存储当前需要传递的book对象 var currentBook: Book? // 实现delegate方法,处理跳转逻辑 func videoOpen(value: Bool) { guard let youtubeVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YoutubeVideoViewController") as? YoutubeVideoViewController else { return } youtubeVC.book = currentBook youtubeVC.boolvalue = value // 选择跳转方式:弹窗或推入导航栈 self.present(youtubeVC, animated: true) // self.navigationController?.pushViewController(youtubeVC, animated: true) } }
- 修正
YoutubeVideoViewController代码,移除错误的videoOpen实现,优化视频加载逻辑:
import UIKit import YoutubePlayer_in_WKWebView class YoutubeVideoViewController: UIViewController , WKYTPlayerViewDelegate { var boolvalue = true var book : Book? @IBOutlet weak var playerView: WKYTPlayerView! override func viewDidLoad() { super.viewDidLoad() playerView.delegate = self // 用可选绑定避免强制解包崩溃 if let mediaKey = book?.mediaKey as? String { playerView.load(withVideoId: mediaKey) } } // 实现WKYTPlayerViewDelegate的必要方法 }
额外注意事项
- 确保
BookDetailVideoViewController中bookImageView的isUserInteractionEnabled已设为true(你的代码中已正确设置)。 - 若
BookDetailVideoViewController作为子视图添加,需保证视图层级和生命周期方法调用正确(如didMove(toParent:))。 - 避免使用强制解包(如
book!.mediaKey),改用可选绑定防止运行时崩溃。
内容的提问来源于stack exchange,提问作者Büşra Güler
相关产品推荐
相关产品推荐

