嵌入式视图控制器中的 UICollectionView 不调用 cellForItemAtIndexPath

UICollectionView in embedded view controller does NOT call cellForItemAtIndexPath

我在一个视图中垂直嵌入了 2 个视图控制器。查看控制器 A(上传器)和 B(docList)。 B 包含一个 UICollectionView

集合视图的数据源中除 cellForItemAtIndexPath 之外的所有方法都被正确调用,我仔细检查了所有内容。有1节。有超过 0 行。我 return 的行的大小小于集合视图等

这是一个说明设置的图表:

我的问题是: 除非我将 setTranslatesAutoresizingMaskIntoConstraints 设置为 YES,否则永远不会调用 cellForItemAtIndexPath。如果我在 View Controller B 的视图中将 属性 设置为 YES,它就会被调用。但是布局然后就搞砸了,因为我没有使用弹簧和 struts。我们这里只使用约束。

你知道在嵌入包含 UICollectionView 的视图控制器时我会做错什么吗?

下面是嵌入两个视图控制器视图并将它们设置为子控制器的代码:

 - (MFFormBaseCell *)cellForComponent
    {
self.cell = [[MFFormBaseCell alloc] initWithFrame:CGRectZero];
[self.cell addSubview: uploader.view];
[self.cell addSubview: docList.view];

UIView* uploaderView = uploader.view;
UIView* docListView = docList.view;

NSMutableArray* tempConstraints = [[NSMutableArray alloc]init];

[tempConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat: @"V:|-8-[uploaderView]-1-[docListView]-8-|"
                                             options: NSLayoutFormatDirectionLeadingToTrailing metrics:nil
                                               views: NSDictionaryOfVariableBindings(uploaderView, docListView)]];


[tempConstraints addObjectsFromArray:
 [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-[uploaderView]-|"
                                         options: NSLayoutFormatDirectionLeadingToTrailing metrics:nil
                                           views: NSDictionaryOfVariableBindings(uploaderView)]];

[tempConstraints addObjectsFromArray:
 [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-[docListView]|"
                                         options: NSLayoutFormatDirectionLeadingToTrailing metrics:nil
                                           views: NSDictionaryOfVariableBindings(docListView)]];

uploaderConstraints = [tempConstraints copy];
[self.cell addConstraints: uploaderConstraints];

[self.embedder addChildViewController:uploader];
[uploader didMoveToParentViewController:self.embedder];



[self.embedder addChildViewController:docList];
[docList didMoveToParentViewController:self.embedder];
docList.view.frame = self.cell.bounds;


return self.cell;

}

这里是视图控制器 B 的代码,它为它设置了 UICollectionView 和垂直流布局。

- (void)modelDidLoad
{

    _dataSource = [[MFCardDataSource alloc] initWithData: self.cardModel];;

    UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];


    [aFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];

    _collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:aFlowLayout];
    [_collectionView setDelegate: self];
    [_collectionView setDataSource:_dataSource];
    [_collectionView setBackgroundColor:[UIColor clearColor]];

    for (NSString* type in [MFCardCollectionModel typeArray])
        [_collectionView registerClass:[MFImageCard class] forCellWithReuseIdentifier: type];

    [_collectionView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.view addSubview:_collectionView];

    [self registerConstraintsForView:_collectionView];

    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

    [super modelDidLoad];

}

以及registerConstraintsForView的内容:

-(void) registerConstraintsForView:(UIView*)collectionView
{
    NSDictionary* metrics = @{ @"padding": @PADDING  };

    NSDictionary* views = NSDictionaryOfVariableBindings(_collectionView);
    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"V:|-padding-[_collectionView]-padding-|"
                               options:NSLayoutFormatDirectionLeadingToTrailing
                               metrics:metrics
                               views:views]];

    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|-padding-[_collectionView]-padding-|"
                               options:NSLayoutFormatDirectionLeadingToTrailing
                               metrics:metrics
                               views:views]];
}

我通过子类化 UICollectionView 并改用子类解决了这个问题。

在子类上我覆盖了 2 个方法:

- (void) setContentSize:(CGSize)contentSize
{
    CGSize origSize = self.contentSize;
    [super setContentSize:contentSize];
    if (!CGSizeEqualToSize(contentSize, origSize))
    {
        [self invalidateIntrinsicContentSize];
    }
}

- (CGSize) intrinsicContentSize
{
    return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
}

然后,我的视图控制器中有一个包含集合视图的方法,它计算集合视图所需的高度。
然后,我在我的 Collection View 子类上使用计算出的高度调用 setContentSize,这确保它 returns 一个 intrinsicContentSize 与显示其中所有卡片记录所需的高度一样高。