2012-12-06 20 views
17

Tôi muốn hiển thị hình ảnh trong lưới trên iPhone bằng UICollectionView, hiển thị 3 hình ảnh liên tiếp. Đối với một "thử nghiệm đơn giản chết" (như tôi nghĩ), tôi đã thêm 15 hình ảnh JPG vào dự án của tôi, để chúng nằm trong gói của tôi và tôi có thể tải chúng đơn giản qua [UIImage imageNamed: ...].UICollectionView đơn giản để hiển thị hình ảnh hoạt động lạ: Một số hình ảnh được hiển thị chính xác, một số ở vị trí sai, một số bị thiếu ở tất cả

Tôi nghĩ rằng tôi đã làm mọi thứ đúng (thiết lập & đăng ký UICollectionViewCell lớp con, sử dụng các phương pháp UICollectionViewDataSource Protocol), tuy nhiên, UICollectionView cư xử rất lạ:

Nó cho thấy chỉ có một vài trong số những hình ảnh trong những điều sau đây pattern: Dòng đầu tiên hiển thị hình ảnh 1 & 3, dòng thứ hai trống, dòng tiếp theo giống như dòng đầu tiên (hình 1 & 3 hiển thị chính xác), dòng thứ tư trống ...

Nếu tôi nhấn một nút trong NavBar của tôi kích hoạt [self.collectionView reloadData], các ô ngẫu nhiên xuất hiện hoặc di chuyển sappear. Điều gì khiến tôi phát điên vì đó không chỉ là vấn đề hình ảnh xuất hiện hay không. Đôi khi, hình ảnh cũng trao đổi giữa các ô, nghĩa là chúng xuất hiện cho một indexPath chúng chắc chắn không có dây!

Đây là mã của tôi cho các tế bào:

@interface AlbumCoverCell : UICollectionViewCell 
@property (nonatomic, retain) IBOutlet UIImageView *imageView; 
@end 

@implementation AlbumCoverCell 
@synthesize imageView = _imageView; 
- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     _imageView = [[UIImageView alloc] initWithFrame:frame]; 
     [self.contentView addSubview:_imageView]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [_imageView release]; 
    [super dealloc]; 
} 

- (void)prepareForReuse 
{ 
    [super prepareForReuse]; 
    self.imageView.image = nil; 
} 
@end 

Một phần của mã cho lớp con UICollectionViewController của tôi, nơi 'imageNames' là một NSArray giữ tất cả tên tập tin jpg:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.collectionView registerClass:[AlbumCoverCell class] forCellWithReuseIdentifier:kAlbumCellID]; 
} 

#pragma mark - UICollectionViewDataSource Protocol methods 
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{ 
    return [self.imageNames count]; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    AlbumCoverCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kAlbumCellID forIndexPath:indexPath]; 
    NSString *imageName = [self.imageNames objectAtIndex:indexPath.row]; 
    NSLog(@"CV setting image for row %d from file in bundle with name '%@'", indexPath.row, imageName); 
    cell.imageView.image = [UIImage imageNamed:imageName]; 

    return cell; 
} 

#pragma mark - UICollectionViewDelegateFlowLayout Protocol methods 
- (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(0, 0, 0, 0); 
} 

Từ NSLog tuyên bố trong cellForItemAtIndexPath: Tôi có thể thấy rằng phương thức được gọi cho tất cả các ô (không chỉ của các ô được hiển thị) và ánh xạ giữa indexPath.row và tên tệp là chính xác.

Có ai có ý tưởng gì có thể gây ra hành vi kỳ quặc này không?

Trả lời

50

Trong thời gian chờ đợi, tôi đã tìm thấy giải pháp. Nó thực sự là một lỗi rất tinh tế trong việc thực hiện của tôi UICollectionViewCell subclass AlbumCoverCell.

Vấn đề là tôi đã đặt khung của ô thể hiện dưới dạng khung của tiểu sử UIImageView thay vì chuyển thuộc tính giới hạn của ô contentView của ô!

Đây là việc sửa chữa:

@implementation AlbumCoverCell 
@synthesize imageView = _imageView; 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // WRONG: 
     // _imageView = [[UIImageView alloc] initWithFrame:frame]; 

     // RIGHT: 
     _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; 
     [self.contentView addSubview:_imageView]; 
    } 
    return self; 
} 


- (void)prepareForReuse 
{ 
    [super prepareForReuse]; 

    // reset image property of imageView for reuse 
    self.imageView.image = nil; 

    // update frame position of subviews 
    self.imageView.frame = self.contentView.bounds; 
} 

... 

@end 
+4

Tôi đã phạm sai lầm tương tự - nhờ niêm yết giải pháp bạn tìm thấy! – krider2010

+2

@Tafkadasoh Cảm ơn bạn! Nó cố định vấn đề của tôi ngay lập tức, tôi đã bắt đầu đánh đầu vào tường .. –

+2

@Tafkadasoh OMG! Cảm ơn bạn rất nhiều! Đã khắc phục sự cố của tôi. Đó là điều nhỏ nhất, nhưng đó là một lỗi khó chịu. Cảm ơn một lần nữa vì đã đăng bài này. Tôi thực sự, thực sự đánh giá cao nó. – GangstaGraham

Các vấn đề liên quan