UIView 容器内的 UICollectionView:滚动后不会调用 didSelectRowAtIndexPath

UICollectionView inside UIView container: didSelectRowAtIndexPath doesn't get called after scroll

我在 ViewController 中嵌入了 3 个 UIViews Header / Tabar / Container 和一个 ScrollView。所以这是我的结构:

在 ContainerView 中我加载了一个 UICollectionView(像这样):

let controller = storyboard!.instantiateViewControllerWithIdentifier("myCollectionViewController") as! myCollectionViewController
controller.delegate = self

self.addChildViewController(controller)
controller.view.backgroundColor = UIColor.brownColor()
self.containerView.addSubview(controller.view)
controller.didMoveToParentViewController(self)

一切正常,UICollectionView 的每个单元格都已加载,...唯一的问题是,所有隐藏的单元格(甚至隐藏的单元格的所有部分)都不可选择。我的意思是我的函数 "didSelectRowAtIndexPath" 不适用于第一个屏幕外的每个像素。这是我的问题的方案:

这是我在滚动之前的内容(左边是一个方案,右边是我在屏幕上的实际内容)-> 这里一切正常:

这是滚动后的内容(左边是方案,右边是我实际在屏幕上的内容)-> 只有像素在滚动之前显示可以调用 "didSelectRowAtIndexPath" :

问题出在self.view.frame刷新效果不佳。您知道我应该如何以及何时更改此框架吗?

您必须定义滚动视图内容的大小

为您的滚动视图创建一个出口

@IBOutlet weak var scrollview : UIScrollView!

使其高度等于header、tabBar和container的高度之和:

self.scrollView.contentSize = CGSizeMake(self.view.frame.width, header.frame.height + tabBar.frame.height + container.frame.height)

问题定义:

我们一直面临的情况是 UIViewController,除了滚动视图外,还显示 headers 和标签栏。问题是那些额外的视图减少了与我们的滚动条相关的区域(在本例中 UICollectionView)。在小屏幕设备中,我们的滚动条将一次显示少量项目。

建议的解决方案:

Let those additional views scrolls along with the scroller items.

如何申请?!

最方便的解决方案。出现在 Scroller View 本身中。例如,UICollectionView 提供 补充元素 (Headers 和页脚),它与 collection 视图项目一起滚动。将 header 和标签栏移动到 UICollectionView 的 header 区域。然后,在您的视图控制器中实现 viewForSupplementaryElementOfKind

- (nonnull UICollectionReusableView *)collectionView:(nonnull UICollectionView *)collectionView viewForSupplementaryElementOfKind:(nonnull NSString *)kind atIndexPath:(nonnull NSIndexPath *)indexPath
{
    UICollectionReusableView *reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"Header1" forIndexPath:indexPath];

    return reusableview;
}

界面生成器: UICollectionView 的 header 区域已经存在。但是,您需要通过界面生成器 in-order 为其设置 高度 以显示在设计时。不要忘记为 header.

设置 Collection 可重用视图标识符

注意:这还需要您做一些额外的工作才能在 header 和 TabBar 上设置手势。

更新:

考虑删除 header 和标签栏容器,并 re-add 将其作为运行时适当位置的子视图。单击 UICollectionView 选项卡时,将其传递给 viewForSupplementaryElementOfKind 方法中的 header 可重用视图。单击标签选项卡时,将其添加到标签容器视图的顶部。当它是一个表视图时,将它传递给 headerForRow 方法中的 UITableView header。

这似乎是您遇到的另一个问题 mentioned in another question 的延续。

查看故事板层次结构,我怀疑问题是,当您更改滚动视图内容大小和 collection 视图高度时,您没有更改 tab bar view 的高度。 Collection 视图仍然可见,可能是因为您的容器 tab bar view 没有剪辑内容 (clipToBounds=false)。但是由于视图本身并没有延伸到下面那么远,因此视图及其子视图无法识别触摸。

确保您的主视图、滚动视图的内容视图(内容大小)、标签栏视图和 collection 视图都已正确调整大小。由于您决定不使用标准视图层次结构(补充视图或 header 视图),因此您必须自己处理管理视图边界的开销。