Swift中UIPageViewController调用setViewControllers切换页面无响应
问题根源与解决方案
你遇到的问题核心很明确:你在侧边菜单里创建了一个全新的FrontContentController实例,而代理指向的是这个看不见的新实例,不是当前屏幕上正在显示的那个。所以当你点击按钮调用changeColor时,确实执行了setViewControllers,但操作的是一个没有被添加到视图层级的控制器,自然看不到页面切换效果。
具体问题分析
在SideMenuController的viewDidLoad里,你做了这样的操作:
frontContentPC = (storyboard.instantiateViewController(withIdentifier: "FrontContent") as! FrontContentController) self.delegate = frontContentPC
这段代码会创建一个全新的FrontContentController对象,但这个对象和你之前在屏幕上显示的那个完全是两个独立的实例。你调用代理方法时,修改的是这个新实例的页面,而不是用户正在看的那个。
修复步骤
我们需要让侧边菜单的代理直接指向当前已经显示的FrontContentController实例,而不是新建一个。
1. 修改FrontContentController的代码
在创建侧边菜单控制器的时候,直接把当前实例设置为它的代理:
override func viewDidLoad() { super.viewDidLoad() self.delegate = self self.dataSource = self // 实例化侧边菜单时,直接绑定当前控制器为代理 self.sideMenuVC = storyboard?.instantiateViewController(withIdentifier: "SideMenu") as! SideMenuController self.sideMenuVC.delegate = self // 这行是关键! self.setViewControllers([subViewControllers[0]], direction: .forward, animated: true, completion: nil) }
2. 简化SideMenuController的代码
移除侧边菜单内部新建FrontContentController的逻辑,不需要自己创建实例,直接使用外部传入的代理:
import UIKit protocol sideMenuDelegate: AnyObject { func changeColor(_ color : UIColor) } class SideMenuController: UIViewController { weak var delegate : sideMenuDelegate? override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black // 删掉这里实例化frontPageVC和frontContentPC的代码 } @IBAction func pressBlueButton(_ sender: Any) { delegate?.changeColor(.blue) } @IBAction func pressRedButton(_ sender: Any) { delegate?.changeColor(.red) } }
额外注意事项
- 确保你的侧边菜单是通过正确的方式展示的(比如侧边栏、popover等),不要重新push/present一个新的侧边菜单实例,否则代理绑定会失效。
- 你用
weak修饰代理的做法是正确的,这能避免循环引用,继续保持这个习惯。
这样修改后,点击侧边菜单的按钮时,就会操作当前屏幕上的UIPageViewController,页面切换应该就能正常工作了。
内容的提问来源于stack exchange,提问作者Karbonyth
相关产品推荐
相关产品推荐

