我一直在尝试让集合视图在 iOS 中正常工作。 我一直在关注这个问题: 如何创建自定义 UICollectionViewCell
我认为我大部分内容都是正确的,我完全使用教程自定义单元类(请参阅代码链接),但是当我使用集合视图访问视图控制器时,我不断遇到错误。
这是我的代码:
#import "BackPackController.h"
#import "UICollectionViewCell+CollectionViewCell.h"
@interface BackPackController () <UICollectionViewDelegate, UICollectionViewDataSource>
@end
@implementation BackPackController
NSArray *itemArray; //our item array
- (void)viewDidLoad {
[super viewDidLoad];
itemArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"PlayerItems"]; //get the players items from the user defaults and make an array of them
_itemGrid.delegate = self;
_itemGrid.dataSource = self;
//[_itemGrid setDataSource:self];
//[_itemGrid registerClass:CollectionViewCell.self forCellWithReuseIdentifier:@"cell1"];
}
- (nonnull __kindof UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
NSLog(@"Got this far");
CollectionViewCell *cell1 = [_itemGrid dequeueReusableCellWithReuseIdentifier:@"cell1" forIndexPath:indexPath];
[cell1.customLabel setText:itemArray[indexPath.row]];
return cell1;
}
- (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return itemArray.count;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(100, 100);
}
据我所知,我已正确连接控制器作为委托和数据源。上面代码中的 NSLog 确实打印了它的消息,所以我知道正在调用 cellForItemAtIndexPath 方法。然而,一旦调用它,我就会收到此错误,并且我正在努力了解到底是什么导致了它:
2023-11-16 08:36:19.163928+1300 Matoran Quest[7698:1793467] *** Assertion failure in -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:], UICollectionView.m:3389
2023-11-16 08:36:19.164525+1300 Matoran Quest[7698:1793467] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the collection view's data source returned nil from -collectionView:cellForItemAtIndexPath: for index path <NSIndexPath: 0x8db3e297ef8cf73e> {length = 2, path = 0 - 0}'
正在访问的列表是一个简单的字符串列表,我知道它运行正常,因为我在其他地方访问它没有问题。我尝试将添加到单元格的文本更改为@“test”,但这没有任何改变
使用以下代码:
UICollectionViewCell+CollectionViewCell.h - *注意:不确定为什么你这样命名你的文件...通常,“Class+Name”用于 Category ...但是,假设类中的代码看起来像这样:
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CollectionViewCell : UICollectionViewCell
@property (strong, nonatomic) IBOutlet UILabel *customLabel;
@end
NS_ASSUME_NONNULL_END
UICollectionViewCell+CollectionViewCell.m
#import "UICollectionViewCell+CollectionViewCell.h"
@implementation CollectionViewCell
@end
BackPackController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface BackPackController : UIViewController
@property (strong, nonatomic) IBOutlet UICollectionView *itemGrid;
@end
NS_ASSUME_NONNULL_END
BackPackController.m
#import "BackPackController.h"
#import "UICollectionViewCell+CollectionViewCell.h"
@interface BackPackController () <UICollectionViewDelegate, UICollectionViewDataSource>
@end
@implementation BackPackController
NSMutableArray *itemArray;
- (void)viewDidLoad {
[super viewDidLoad];
itemArray = [NSMutableArray new];
// let's generate a simple string array
for (int i = 0; i < 40; i++) {
NSString *s = [NSString stringWithFormat:@"%i", i];
[itemArray addObject:s];
}
_itemGrid.dataSource = self;
_itemGrid.delegate = self;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return itemArray.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *c = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell1" forIndexPath:indexPath];
[c.customLabel setText:itemArray[indexPath.item]];
return c;
}
@end
UIViewController
并将其类分配给
BackPackController
将单元格原型的类分配给CollectionViewCell
,并将其标识符设置为“cell1”(不带引号)。添加一个
UICollectionView
并在所有 4 条边上用 20 个点对其进行约束。给它和它的默认单元格对比背景颜色,这样我们就可以看到它。向单元原型添加
UILabel
,并将其约束为居中。将
IBOutlet UILabel *customLabel
连接到单元格中的标签。将
IBOutlet UICollectionView *itemGrid
连接到控制器中的集合视图。应该看起来像这样(忽略故事板中的其他控制器):
运行应用程序时,您应该看到以下内容:
现在您可以开始在 UserDefaults 中实现“PlayerItems”,添加搜索栏等。