【问题标题】:UICollectionView consuming vertical pan gestureUICollectionView 消耗垂直平移手势
【发布时间】:2021-11-28 19:40:07
【问题描述】:

我有一个 UICollectionView,它位于 UITableView 内,并且位于 UIScrollView 内。集合视图是项目的水平滚动轮播,如果集合视图中有足够的项目以使其比屏幕宽度更宽,则可以正常工作。但是我遇到的问题是,如果只有一两个项目(不足以填满屏幕的宽度),那么集合视图似乎会消耗垂直平移手势,并且不会让滚动视图滚动。

这是我的应用程序目前的布局方式。有滚动视图(下图中的绿色),其中包含页面上的所有内容。在其中,有一个包含多个部分的表格视图。每个部分都有一个可点击的部分标题。点击部分标题后,该部分会通过添加包含集合视图的一行来扩展。集合视图是一个水平滚动的流布局集合视图。

只要集合视图中有足够的集合视图单元格使其离开屏幕(如上图所示。但如果只有一个项目,例如(如下一张图片),则如果平移手势开始于集合视图内的任何位置(下图中蓝色区域或棕褐色区域的任何位置),则滚动视图无法垂直滚动。

代码

这里是初始化集合视图的代码:

- (UICollectionView *)collectionView {
    if (!self->_collectionView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.minimumInteritemSpacing = 10;
        layout.minimumLineSpacing = 10;
        
        layout.sectionInset = UIEdgeInsetsMake(0, 16, 0, 16);
        layout.sectionInsetReference = UICollectionViewFlowLayoutSectionInsetFromContentInset;
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        
        self->_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
        self->_collectionView.translatesAutoresizingMaskIntoConstraints = NO;
        self->_collectionView.backgroundColor = nil;
        self->_collectionView.delegate = self;
        self->_collectionView.dataSource = self;
        
        [self.collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyCollectionViewCell"];
    }
    return self->_collectionView;
}

问题

有谁知道为什么只有一两个项目时集合视图会消耗垂直平移手势或如何解决?

【问题讨论】:

    标签: ios uicollectionview uiscrollview uigesturerecognizer uicollectionviewflowlayout


    【解决方案1】:

    这三个视图实际上都是滚动视图。 UITableViewUICollectionView 类继承自 UIScrollView

    UIScrollView 通过其panGestureRecognizer 识别滚动。

    由于您没有在滚动视图中定义这些识别器之间的依赖关系,因此触摸事件的使用方式如下:

    • 所有识别器都会收到触摸(UIScrollView 就是这样预配置的)
    • 如果命中测试视图的识别器没有失败,它会处理平移手势
    • 如果失败,超级视图的识别器会尝试处理手势。

    这种级联的平移处理会像这样在视图层次结构中上升,直到处理完手势或不再有滚动视图。

    在您的情况下,当集合视图的内容大小小于或等于其边界大小时,具有水平滚动的集合视图的平移识别器不会因垂直滚动而失败。

    你可以尝试两件事。要么要求集合视图平移识别器的滚动视图平移识别器失败

    [self->_collectionView.panGestureRecognizer requireGestureRecognizerToFail:scrollView.panGestureRecognizer]
    

    或在内容大小小于边界时禁用集合视图的滚动。为此,您可以创建UICollectionView 的子类,覆盖setContentSize:setBounds: 方法并相应地分配scrollEnabled。然后使用你的子类而不是原版的UICollectionView

    【讨论】:

    • 非常感谢您的帮助。我喜欢第一个选项,其中手势识别器需要另一个手势识别器失败,但是当我这样做时,它现在使水平滚动真正延迟,因为系统在允许集合视图滚动之前等待滚动视图的平移手势失败。当内容太小时,我将尝试禁用滚动的第二种解决方案。但是你知道为什么会发生这种情况吗?将集合视图放在表格视图中可能会出现问题吗?表格视图已禁用滚动。再次感谢。
    • 我不知道为什么会这样。在表格视图中包含集合视图是许多应用程序使用的正常场景。对于第一个解决方案,您还可以检查两个识别器是否都有.delegate == nil,如果有,则将self指定为两者的代表,并实现gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer)并返回true。这样可以防止延误。
    猜你喜欢
    • 2012-09-23
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2015-01-27
    • 2017-02-10
    相关资源
    最近更新 更多