嵌入式视图控制器中的 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 与显示其中所有卡片记录所需的高度一样高。
我在一个视图中垂直嵌入了 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 与显示其中所有卡片记录所需的高度一样高。