Ios 在UIScrollView中嵌套的UICollectionView之间连续垂直滚动
虽然我知道嵌套的滚动视图并不理想,但我们的设计师为我提供了这种设置,所以我正在尽最大努力使其工作。让我们开始吧 查看层次结构Ios 在UIScrollView中嵌套的UICollectionView之间连续垂直滚动,ios,objective-c,uiscrollview,uicollectionview,ios8,Ios,Objective C,Uiscrollview,Uicollectionview,Ios8,虽然我知道嵌套的滚动视图并不理想,但我们的设计师为我提供了这种设置,所以我正在尽最大努力使其工作。让我们开始吧 查看层次结构 UIView UIScrollView(仅限垂直滚动) UIImageView UICollectionView#1(仅限水平滚动) UIImageView(与以前的UIImageView不同) UICollectionView#2(仅限垂直滚动) 重要提示 我的所有视图都是使用编程自动布局定义的。UIScrollView的子视图层次结构中的每个连续视图都对之
- UIView
- UIScrollView(仅限垂直滚动)
- UIImageView
- UICollectionView#1(仅限水平滚动)
- UIImageView(与以前的UIImageView不同)
- UICollectionView#2(仅限垂直滚动)
- UIScrollView(仅限垂直滚动)
将参考\u outerScrollView
UIScrollView
将参考\u innerScrollView
UICollectionView#2
\u outerScrollView
在到达其contentSize的底部时将其触摸事件路由到\u innerScrollView
。我希望在向上滚动时发生相反的情况
目前,我有以下代码:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat bottomEdge = [scrollView contentOffset].y + CGRectGetHeight(scrollView.frame);
if (bottomEdge >= [_outerScrollView contentSize].height) {
_outerScrollView.scrollEnabled = NO;
_innerScrollView.scrollEnabled = YES;
} else {
_outerScrollView.scrollEnabled = YES;
_innerScrollView.scrollEnabled = NO;
}
}
初始条件(在任何滚动发生之前)设置为:
outerScrollView.scrollEnabled = YES;
innerScrollView.scrollEnabled = NO;
发生了什么事?
触摸视图时,outerScrollView
滚动至其底部边缘,然后由于\u outerScrollView.bounces=YES而产生橡皮筋效果代码>如果我再次触摸视图,innerScrollView将滚动,直到它到达其底部边缘。在倒车过程中,同样的橡皮筋效果以相反的顺序出现。我希望在两个子视图之间有一个流体运动
显然,这是由于在代码段的条件中设置了滚动启用的
条件。我想弄清楚的是如何在碰到边缘时将一个scrollView的速度/速度路由到下一个scrollView
在此问题上的任何协助都将不胜感激
其他注释
这对我不起作用:
我正在考虑将UIScrollView层次结构中的所有内容(除了UICollectionView#2)放在UICollectionView#2补充视图中。不确定这是否有效
明白了
第一:
\u scrollView.paginabled=YES代码>
第二:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == _scrollView || scrollView == _offersCollectionView) {
CGFloat offersCollectionViewPosition = _offersCollectionView.contentOffset.y;
CGFloat scrollViewBottomEdge = [scrollView contentOffset].y + CGRectGetHeight(scrollView.frame);
if (scrollViewBottomEdge >= [_scrollView contentSize].height) {
_scrollView.scrollEnabled = NO;
_offersCollectionView.scrollEnabled = YES;
} else if (offersCollectionViewPosition <= 0.0f && [_offersCollectionView isScrollEnabled]) {
[_scrollView scrollRectToVisible:[_scrollView frame] animated:YES];
_scrollView.scrollEnabled = YES;
_offersCollectionView.scrollEnabled = NO;
}
}
}
-(无效)scrollViewDidScroll:(UIScrollView*)scrollView
{
如果(scrollView==_scrollView | | scrollView==_OfferCollectionView){
CGFloat offersCollectionView位置=_offersCollectionView.contentOffset.y;
CGFloat scrollViewBottomEdge=[scrollView contentOffset].y+CGRectGetHeight(scrollView.frame);
如果(scrollViewBottomEdge>=[[u scrollView contentSize].高度){
_scrollView.scrollEnabled=否;
_OfferCollectionView.scrollEnabled=是;
}否则,如果(OfferCollectionViewPosition接受的答案对我不起作用。下面是我所做的:
定义UIScrollView
的子类:
class CollaborativeScrollView: UIScrollView, UIGestureRecognizerDelegate {
var lastContentOffset: CGPoint = CGPoint(x: 0, y: 0)
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return otherGestureRecognizer.view is CollaborativeScrollView
}
}
由于不可能将触摸重新路由到另一个视图,因此确保外部滚动视图在内部滚动视图停止后可以继续滚动的唯一方法是如果它一直在接收触摸。但是,为了防止外部滚动视图在内部滚动时移动,我们必须在不设置其IsScrole的情况下锁定它nabled
到false
,否则它将停止接收触摸,并且当我们想要滚动到内部一个的顶部或底部时,它将无法拾取内部一个停止的位置
通过将UIScrollViewDelegate
分配给ScrollView,并实现scrollViewDidScroll(:)
,如图所示:
class YourViewController: UIViewController, UIScrollViewDelegate {
private var mLockOuterScrollView = false
@IBOutlet var mOuterScrollView: CollaborativeScrollView!
@IBOutlet var mInnerScrollView: CollaborativeScrollView!
enum Direction {
case none, left, right, up, down
}
func viewDidLoad() {
mOuterScrollView.delegate = self
mInnerScrollView.delegate = self
mInnerScrollView.bounces = false
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard scrollView is CollaborativeScrollView else {return}
let csv = scrollView as! CollaborativeScrollView
//determine direction of scrolling
var directionTemp: Direction?
if csv.lastContentOffset.y > csv.contentOffset.y {
directionTemp = .up
} else if csv.lastContentOffset.y < csv.contentOffset.y {
directionTemp = .down
}
guard let direction = directionTemp else {return}
//lock outer scrollview if necessary
if csv === mInnerScrollView {
let isAlreadyAllTheWayDown = (mInnerScrollView.contentOffset.y + mInnerScrollView.frame.size.height) == mInnerScrollView.contentSize.height
let isAlreadyAllTheWayUp = mInnerScrollView.contentOffset.y == 0
if (direction == .down && isAlreadyAllTheWayDown) || (direction == .up && isAlreadyAllTheWayUp) {
mLockOuterScrollView = false
} else {
mLockOuterScrollView = true
}
} else if mLockOuterScrollView {
mOuterScrollView.contentOffset = mOuterScrollView.lastContentOffset
}
csv.lastContentOffset = csv.contentOffset
}
}
class YourViewController:UIViewController、UIScrollViewDelegate{
私有变量mLockOuterScrollView=false
@IBMOutlet var mOuterScrollView:CollaborativeScrollView!
@IBMOutlet var mInnerScrollView:CollaborativeScrollView!
枚举方向{
案例无,左,右,上,下
}
func viewDidLoad(){
mOuterScrollView.delegate=self
mInnerScrollView.delegate=self
mInnerScrollView.bounces=false
}
func scrollViewDidScroll(scrollView:UIScrollView){
guard scrollView是CollaborativeScrollView else{return}
让csv=scrollView为!CollaborativeScrollView
//确定滚动的方向
var directionTemp:方向?
如果csv.lastContentOffset.y>csv.contentOffset.y{
方向温度=.up
}否则,如果csv.lastContentOffset.y
就是这样。当您开始滚动内部滚动视图时,这将阻止外部滚动视图的滚动,并且当内部滚动视图一直滚动到其一端时,它将再次被拾取。我在Twitter上被一位熟人引用到以下视频:。我是c