我有一个 UICollectionView,它从 web 服务接收数据。根据它收到的数据,它在我的 UICollectionView 上绘制单元格。每个单元格都是一个扩展 UICollectionViewCell 的自定义类。每个 UICollectionViewCell 都是通过 .nib 加载的。我的 init 方法如下所示:
@implementation GridCell
- (id)initWithFrame:(CGRect)frame
{
if (self)
{
// Initialization code
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"GridCell" owner:self options:nil];
if ([arrayOfViews count] < 1) {
return nil;
}
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
return nil;
}
self = [arrayOfViews objectAtIndex:0];
// It is important that you set the properties of the view after the above assignment
// because self is assigned to the nib after that call.
self.layer.masksToBounds = NO;
self.layer.shadowColor = [[UIColor blackColor] CGColor];
self.layer.shadowOffset = CGSizeMake(0.0, 1.0);
self.layer.shadowOpacity = 0.17;
self.layer.shadowRadius = 0.35f;
self.layer.shouldRasterize = YES;
}
return self;
}
我有一个 GridViewController ,它基本上是一个 UIViewController :
@implementation GridViewController
- (id)initWithSize:(CGFloat)frameWidth :(CGFloat)frameHeight {
self = [super init];
if(self) {
// Have the getGridView returning the initialized view
// then assign it to the GridViewControllers view property
self.view = [self getGridView:frameWidth:frameHeight];
}
return self;
}
-(UIView *)getGridView:(CGFloat)width :(CGFloat)height {
UIView *gridHolder = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc]init];
[flow setScrollDirection:UICollectionViewScrollDirectionHorizontal];
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat screenheight = screen.size.height;
// It is an iphone 5, setup the cellsize and the spacing between cells.
if(screenheight > 480) {
[flow setItemSize:CGSizeMake( (gridHolder.frame.size.width / 1.85) , (gridHolder.frame.size.height / 3.25) )];
[flow setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[flow setMinimumInteritemSpacing:0];
[flow setMinimumLineSpacing:10];
// It is an iphone 4, setup the cellsize and the spacing between cells.
} else {
[flow setItemSize:CGSizeMake( (gridHolder.frame.size.width / 2.5) , (gridHolder.frame.size.height / 3.1) - 10)];
[flow setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[flow setMinimumInteritemSpacing:0];
[flow setMinimumLineSpacing:10];
}
self.grid = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, gridHolder.frame.size.width, gridHolder.frame.size.height) collectionViewLayout:flow];
[_grid setBackgroundColor:[UIColor colorWithRed:0.961 green:0.961 blue:0.961 alpha:1]];
[_grid setDataSource:self];
[_grid setDelegate:self];
[_grid setBounces:NO];
[_grid registerClass:[GridCell class] forCellWithReuseIdentifier:Cell];
[gridHolder addSubview:self.grid];
return gridHolder;
}
这个 UIViewController 也是我的 UICollectionViewDataSource。所以我有以下方法:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [releases count];
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(10, 10, 10, 10);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
GridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:Cell forIndexPath:indexPath];
return cell; // <-- finally return the cell
}
我在单元格上添加了一个 UIButton。我将 IBAction 连接到按钮。但是每次我点击这个按钮时,我都会得到一个空指针异常,因为 GridIcon 已经被 ARC 丢弃了。我必须在某处保留 GridIcon 吗?或者克服这个(简单?)问题的最佳实践是什么?
驻留在我的 GridIcon.m 中的方法是:
- (IBAction)cellClicked {
NSLog(@"test");
}
我的 GridIcon.h 文件有一个 IBAction 描述:
@interface GridCell : UICollectionViewCell
- (IBAction)cellClicked;
@end
编辑 :
jackslash,感谢您花时间和精力让我意识到这个非常疯狂的结构。让我解释一下我是如何设置这个项目的。
我有一个 MainViewController,我在 AppDelegate.m 中将其设置为 RootViewController。然后在我的 MainViewController 中我初始化 2 UIVIewController。其中之一是我的 GridViewController,它设置了 UICollectionView。
所以这个 UICollectionView 的数据源是我初始化的 UIViewController。我需要为此 UIViewController 绘制屏幕区域,因此我将另一个 UIViewController 的高度提供给 GridViewController。而getGridView方法得到的是屏幕高度减去其他UIViewConroller的视图的高度。
结构是这样的:
@interface MainViewController: UIViewController
// These next two classes both extend UIViewController
@property(nonatomic, strong) GridViewController *gridViewcontroller;
@property(nonatomic, strong) BottomBarController *bottomBarcontroller;
@end
在我的 MainViewController.m [viewDidLoad] 中,我都初始化了那些 UIViewcontrollers 并将它们的视图作为 subView 添加到 MainViewController。
那么实现这一目标的最佳方法是什么?我应该将 UICollectionViewController 与我的 GridViewController 分开吗?但是这个 UICollectionView 是如何知道要在屏幕的哪个区域绘制的呢?
对于我的 GridCell 中的 init 方法,我实际上使用它在我的 GridCell 下方绘制了一个阴影。如果没有这个 init 方法,我将如何在我的单元格下面实现绘图?
编辑2: 除了我上面的编辑:
- 我在每个 GridCell 上都有一个 UIImageView 和一个 UILabel。我将如何针对我的代码中的那些?