我的 UICollectionView 没有调用它的数据源方法?

My UICollectionView does not call its datasource methods?

我刚得到一个标准 UIViewController subclass 和 UICollectionViewUICollection 视图未调用其数据源(或委托)方法,但我看不出缺少哪一部分。

这是我的 UIViewController class 的界面,显示了 UICollectionView:

@interface PastViewController ()  <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
...
@property (nonatomic, weak) UICollectionView *collectionView;
@end

这是我的 viewDidLoad(几乎)的全部内容:

- (void)viewDidLoad {

    [super viewDidLoad];    


    UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
    flowLayout.itemSize = CGSizeMake(100, 100);
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

    //self.complaints is used to generate the collection view cells
    //the log always prints out 30 complaints
    self.complaints = [self.complaintDatabase getComplaints ];
    NSLog(@"got a total OF %d complaints", self.complaints.count);

    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height) collectionViewLayout:flowLayout];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.collectionView registerClass:[VideoCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    [self.view addSubview:self.collectionView];


    [self.collectionView reloadData];
    [self.collectionView reloadInputViews];
}

最后我还会 post 数据源、委托和委托流布局协议。没有其他子视图添加到视图控制器,我已经设置了委托并声明了委托协议,因此以下 SO posts 不适用:

我错过了什么?为什么永远不会调用数据源方法(和委托方法)?

以下是为各种协议实现的方法:

#pragma mark - UICollectionViewDataSource

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    NSLog(@"should be seeing %d collection view cells", self.complaints.count);
    return self.complaints.count;
}


- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    NSLog(@"QUERYING NUMBER OF SECTIONS IN COLLECTION VIEW");
    return 1;
}


- (UICollectionViewCell  *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    VideoCollectionViewCell *cell = [[VideoCollectionViewCell alloc] initWithCoder:@"cell"];
    cell.complaint = self.complaints[indexPath.row];
    return cell;
}


#pragma mark - UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"calling didselctitem at path");
}

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"diddeselectitem");
}


#pragma mar - UICollectionViewFlowDelegateLayout

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return CGSizeMake(100, 100);
}


- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(50, 20, 50, 20);
}

@property (nonatomic, strong) UICollectionView *collectionView;

weak改为strong,否则collectionView赋值后会被释放,也就是说collectionView会变成nil,这样数据源方法永远不会被调用。

另一种方法:

保持 collectionViewweak

- (void)viewDidLoad {

    [super viewDidLoad];    


    UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
    flowLayout.itemSize = CGSizeMake(100, 100);
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

    //self.complaints is used to generate the collection view cells
    //the log always prints out 30 complaints
    self.complaints = [self.complaintDatabase getComplaints ];
    NSLog(@"got a total OF %d complaints", self.complaints.count);

    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height) collectionViewLayout:flowLayout];
    collectionView.delegate = self;
    collectionView.dataSource = self;
    [collectionView registerClass:[VideoCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    [self.view addSubview:collectionView];
    self.collectionView = collectionView;

    [self.collectionView reloadData];
    [self.collectionView reloadInputViews];
}

参见:Creating views programmatically Strong Vs Weak subviews in controller