IOS UICollectionView 在使用两个集合视图时抛出断言
IOS UICollectionView throws assertion when using two collection views
我在一个 UIViewController 中有两个 UICollectionView。我通过标记号将它们分开,以便我可以对两者使用数据源和委托方法。但是,当我 运行 代码崩溃时出现异常:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0xc000000000200016> {length = 2, path = 0 - 1}'
.
我在论坛上查了这个,大多数人说你需要使 UIControllerView 失效然后重新加载,但在我的情况下这是行不通的。
有人知道如何解决这个问题吗?
这是我的代码:
-(void)viewDidLoad {
self.socialMediaGrayIcons = [[NSMutableArray alloc] initWithObjects:[UIImage imageNamed:@"fb-gray.png"],
[UIImage imageNamed:@"twitter-gray.png"],
[UIImage imageNamed:@"insta-gray.png"],
[UIImage imageNamed:@"sms-gray.png"],
[UIImage imageNamed:@"email-gray.png"], nil];
// setup collection view
self.avatarCollectionView.tag = 200;
self.socialMediaCollectionView.tag = 201;
UINib *cellNib = [UINib nibWithNibName:@"NibCell" bundle:nil];
[self.avatarCollectionView registerNib:cellNib forCellWithReuseIdentifier:@"cvCell"];
[self.socialMediaCollectionView registerNib:cellNib forCellWithReuseIdentifier:@"smCell"];
// setup collection view layout
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(40, 40)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.avatarCollectionView setCollectionViewLayout:flowLayout];
[self.socialMediaCollectionView setCollectionViewLayout:flowLayout];
[self.avatarCollectionView reloadData];
[self.avatarCollectionView.collectionViewLayout invalidateLayout];
[self.socialMediaCollectionView reloadData];
[self.socialMediaCollectionView.collectionViewLayout invalidateLayout];
}
....
#pragma mark UICollectionView DataSource and Delegate mathods
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
if (collectionView.tag == 200)
{
return self.children.count;
} else if (collectionView.tag == 201){
return self.socialMediaGrayIcons.count;
}
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
if (collectionView.tag == 200)
{
static NSString *cellIdentifier = @"cvCell";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
Child *currentChild = [self.children objectAtIndex:indexPath.row];
UIImage *curImage = [UIImage imageWithData:currentChild.thumbnail];
UIImageView *thumbView = (UIImageView *)[cell viewWithTag:100];
if (curImage != nil)
{
[thumbView setImage:curImage];
}
} else if (collectionView.tag == 201){
static NSString *cellIdentifier = @"smCell";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImage *curImage = (UIImage*) [self.socialMediaGrayIcons objectAtIndex:indexPath.row];
UIImageView *thumbView = (UIImageView *)[cell viewWithTag:101];
if (curImage != nil)
{
[thumbView setImage:curImage];
}
}
return cell;
}
采纳@Paulw 的好建议是这样的:
@property(weak,nonatomic) IBOutlet UICollectionView *collectionViewA;
@property(weak,nonatomic) IBOutlet UICollectionView *collectionViewB;
您的数据源方法必须始终根据传递的集合视图划分为条件的两个分支,并且始终在一个中使用一个数据源数组,在另一个中使用另一个。
您可以始终通过一种方便的方法获取数据源,例如这样...
- (NSArray *)datasourceForCollectionView:(UICollectionView *)collectionView {
if (collectionView == self.collectionViewA) {
return self.children;
} else { // NOTICE - no else-if, there's no other valid condition
return self.socialMediaGrayIcons;
}
}
随处使用它,例如...
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self datasourceForCollectionView:collectionView].count;
}
我在一个 UIViewController 中有两个 UICollectionView。我通过标记号将它们分开,以便我可以对两者使用数据源和委托方法。但是,当我 运行 代码崩溃时出现异常:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0xc000000000200016> {length = 2, path = 0 - 1}'
.
我在论坛上查了这个,大多数人说你需要使 UIControllerView 失效然后重新加载,但在我的情况下这是行不通的。
有人知道如何解决这个问题吗?
这是我的代码:
-(void)viewDidLoad {
self.socialMediaGrayIcons = [[NSMutableArray alloc] initWithObjects:[UIImage imageNamed:@"fb-gray.png"],
[UIImage imageNamed:@"twitter-gray.png"],
[UIImage imageNamed:@"insta-gray.png"],
[UIImage imageNamed:@"sms-gray.png"],
[UIImage imageNamed:@"email-gray.png"], nil];
// setup collection view
self.avatarCollectionView.tag = 200;
self.socialMediaCollectionView.tag = 201;
UINib *cellNib = [UINib nibWithNibName:@"NibCell" bundle:nil];
[self.avatarCollectionView registerNib:cellNib forCellWithReuseIdentifier:@"cvCell"];
[self.socialMediaCollectionView registerNib:cellNib forCellWithReuseIdentifier:@"smCell"];
// setup collection view layout
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(40, 40)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.avatarCollectionView setCollectionViewLayout:flowLayout];
[self.socialMediaCollectionView setCollectionViewLayout:flowLayout];
[self.avatarCollectionView reloadData];
[self.avatarCollectionView.collectionViewLayout invalidateLayout];
[self.socialMediaCollectionView reloadData];
[self.socialMediaCollectionView.collectionViewLayout invalidateLayout];
}
....
#pragma mark UICollectionView DataSource and Delegate mathods
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
if (collectionView.tag == 200)
{
return self.children.count;
} else if (collectionView.tag == 201){
return self.socialMediaGrayIcons.count;
}
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
if (collectionView.tag == 200)
{
static NSString *cellIdentifier = @"cvCell";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
Child *currentChild = [self.children objectAtIndex:indexPath.row];
UIImage *curImage = [UIImage imageWithData:currentChild.thumbnail];
UIImageView *thumbView = (UIImageView *)[cell viewWithTag:100];
if (curImage != nil)
{
[thumbView setImage:curImage];
}
} else if (collectionView.tag == 201){
static NSString *cellIdentifier = @"smCell";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImage *curImage = (UIImage*) [self.socialMediaGrayIcons objectAtIndex:indexPath.row];
UIImageView *thumbView = (UIImageView *)[cell viewWithTag:101];
if (curImage != nil)
{
[thumbView setImage:curImage];
}
}
return cell;
}
采纳@Paulw 的好建议是这样的:
@property(weak,nonatomic) IBOutlet UICollectionView *collectionViewA;
@property(weak,nonatomic) IBOutlet UICollectionView *collectionViewB;
您的数据源方法必须始终根据传递的集合视图划分为条件的两个分支,并且始终在一个中使用一个数据源数组,在另一个中使用另一个。
您可以始终通过一种方便的方法获取数据源,例如这样...
- (NSArray *)datasourceForCollectionView:(UICollectionView *)collectionView {
if (collectionView == self.collectionViewA) {
return self.children;
} else { // NOTICE - no else-if, there's no other valid condition
return self.socialMediaGrayIcons;
}
}
随处使用它,例如...
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self datasourceForCollectionView:collectionView].count;
}