Core Plot在UIPageViewController中滚动失效的解决方法咨询
解决UIPageViewController嵌套Core Plot图表时滚动失效的问题
这个问题我之前踩过坑,核心原因基本都是Core Plot的图表视图和UIPageViewController的滚动手势发生了冲突,或者是触摸事件的传递优先级没处理好。下面给你几个实测有效的解决方案,按从易到难的顺序来:
1. 调整Core Plot宿主视图的触摸延迟
Core Plot的CPTGraphHostingView默认会延迟处理触摸事件,这会导致UIPageViewController的滚动手势无法及时响应。只需要把这个属性关掉就行:
Swift 代码示例:
// 在包含Core Plot图表的UIViewController中 override func viewDidLoad() { super.viewDidLoad() // 假设你的hostingView是IBOutlet连接的 if let hostingView = self.hostingView as? CPTGraphHostingView { hostingView.delaysContentTouches = false } // 其他图表初始化代码... }
Objective-C 代码示例:
- (void)viewDidLoad { [super viewDidLoad]; CPTGraphHostingView *hostingView = (CPTGraphHostingView *)self.hostingView; hostingView.delaysContentTouches = NO; // 其他图表初始化代码... }
这个方法最简单,大部分情况下都能直接解决问题。
2. 禁用Core Plot图表的内置交互(如果不需要的话)
如果你的图表本身不需要用户交互(比如不需要缩放、拖拽),可以直接禁用它的交互能力,彻底避免手势冲突:
Swift 代码示例:
// 在配置CPTGraph的时候 let graph = CPTXYGraph(frame: .zero) // 禁用整个绘图区域的交互 graph.plotAreaFrame?.allowsUserInteraction = false // 如果你只想禁用滚动手势,保留其他交互(比如点击),可以这样: if let plotArea = graph.plotAreaFrame?.plotArea { for gesture in plotArea.gestureRecognizers ?? [] { if gesture is UIPanGestureRecognizer { gesture.isEnabled = false } } }
3. 提升UIPageViewController滚动手势的优先级
如果上面两种方法都不行,可以通过手势依赖,让UIPageViewController的滚动手势优先触发:
Swift 代码示例:
// 在UIPageViewController的初始化或子控制器添加完成后 if let pagePanGesture = self.gestureRecognizers?.first(where: { $0 is UIPanGestureRecognizer }) { // 获取当前显示的子控制器(带Core Plot的那个) if let currentVC = self.viewControllers?.first as? YourChartViewController { if let hostingView = currentVC.hostingView as? CPTGraphHostingView { // 让Core Plot的所有手势都依赖于页面滚动手势失败 for gesture in hostingView.gestureRecognizers ?? [] { gesture.require(toFail: pagePanGesture) } } } }
4. 检查视图约束与Frame
最后别忘了检查一下子控制器的View是否正确适配了UIPageViewController的Bounds:
- 确保子控制器的View的约束是和UIPageViewController的View边缘对齐的,没有偏移或超出
- 避免手动设置Frame导致的尺寸不匹配,尽量用Auto Layout
先从第一种方法开始试,大概率能解决问题。如果你的图表需要保留自身交互,再尝试后面的方案。
内容的提问来源于stack exchange,提问作者Stas Buldakov
相关产品推荐
相关产品推荐

