我正在尝试构建一个复杂的分割视图容器控制器,该控制器有利于两个可变高度容器,每个容器都有自己的嵌套视图控制器。父控制器上有一个全局平移手势,允许用户拖动视图容器中的任意位置,并在视图之间上下滑动“分隔线”。它还具有一些智能位置阈值检测逻辑,可以扩展任一视图(或重置分隔线位置):
这很好用。还有很多代码可以构建这个,我很乐意分享,但我认为它们不相关,所以我暂时忽略它。
我现在尝试通过向底部视图添加集合视图来使事情变得复杂:
我已经能够解决这个问题,这样我就可以用果断的平移手势向上滚动分割视图,并用快速的手指轻弹滚动集合视图(我想是滑动手势?),但是这个是一种真正低于标准的体验:您无法同时平移视图和滚动集合视图,并且期望用户一致地复制相似但不同的手势来控制视图,这种交互太困难了。
为了尝试解决这个问题,我尝试了几种委托/协议解决方案,其中我检测分割视图中分隔线的位置并启用/禁用canCancelTouchesInView
and/or isUserInteractionEnable
基于底部视图是否完全展开的集合视图。这在一定程度上是有效的,但不适用于以下两种情况:
- 当分割视图分隔线处于默认位置时,如果用户向上平移到底部视图完全展开的位置,然后继续向上平移,则集合视图应开始滚动,直到手势结束。
- 当分割视图分隔线位于顶部(底部容器视图完全展开)且集合视图为not在顶部,如果用户向下平移,集合视图应滚动而不是分割视图分隔线移动,直到集合视图到达其顶部位置,此时分割视图应返回到其默认位置。
下面的动画演示了这种行为:
鉴于此,我开始认为解决问题的唯一方法是在分割视图上创建一个委托方法,该方法告诉集合视图底部视图何时处于最大高度,然后可以拦截父级的平移手势或向前移动屏幕触摸到集合视图吗?但是,我不知道该怎么做。如果我的解决方案是正确的,那么我的问题很简单:如何将平移手势转发或移交给集合视图,并使集合视图以与首先捕获触摸的方式相同的方式进行交互?我可以做点什么吗pointInside
or touches____
方法?
如果我不能这样做,我还能如何解决这个问题?
赏金猎人的更新:我在集合视图上创建委托方法并在拆分视图容器上调用它来设置属性时遇到了一些零碎的运气shouldScroll
,通过它我使用一些平移方向和定位信息来确定滚动视图是否应该滚动。然后我返回这个值UIGestureRecognizerDelegate
's gestureRecognizer:shouldReceive touch:
委托方法:
// protocol delegate
protocol GalleryCollectionViewDelegate {
var shouldScroll: Bool? { get }
}
// shouldScroll property
private var _shouldScroll: Bool? = nil
var shouldScroll: Bool {
get {
// Will attempt to retrieve delegate value, or self set value, or return false
return self.galleryDelegate?.shouldScroll ?? self._shouldScroll ?? false
}
set {
self._shouldScroll = newValue
}
}
// UIGestureRecognizerDelegate method
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return shouldScroll
}
// ----------------
// Delegate property/getter called on the split view controller and the logic:
var shouldScroll: Bool? {
get {
return panTarget != self
}
}
var panTarget: UIViewController! {
get {
// Use intelligent position detection to determine whether the pan should be
// captured by the containing splitview or the gallery's collectionview
switch (viewState.currentPosition,
viewState.pan?.directionTravelled,
galleryScene.galleryCollectionView.isScrolled) {
case (.top, .up?, _), (.top, .down?, true): return galleryScene
default: return self
}
}
}
当您开始滚动时,这可以正常工作,但一旦在集合视图上启用滚动,效果就不佳,因为滚动手势几乎总是覆盖平移手势。我想知道我是否可以连接一些东西gestureRecognizer:shouldRecognizeSimultaneouslyWith:
,但我还没到那儿。