我在不使用故事板的情况下以编程方式创建了UICollectionView
和UICollectionViewCell
,但发生了一些事情,我无法理解原因。
BKPhotoCell
中存在内存泄漏。
单元格是全屏的,但滚动CollectionView
时,它们永远不会重复使用。每个Init
都会调用indexpath.row
。
PrepareForReuse
也从未打过电话。
任何人都可以帮助我理解我做错了什么吗?
- (void)viewDidLoad
{
[super viewDidLoad];
CGSize screenSize = self.view.bounds.size;
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(screenSize.width, screenSize.height)];
[flowLayout setMinimumInteritemSpacing:0.0f];
[flowLayout setMinimumLineSpacing:0.0f];
[flowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0,0, screenSize.width, screenSize.height) collectionViewLayout:flowLayout];
[self.collectionView setDelegate:self];
[self.collectionView setDataSource:self];
[self.collectionView registerClass:[BKPhotoCell class] forCellWithReuseIdentifier:@"BKPhotoCell"];
[self.collectionView setPagingEnabled:YES];
[self.collectionView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.view addSubview:self.collectionView];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
BKPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"BKPhotoCell" forIndexPath:indexPath];
[cell.imageView setImage:[UIImage imageNamed:[_photos objectAtIndex:indexPath.row]]];
return cell;
}
BKPhotoCell.h:
@interface BKPhotoCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *imageView;
@end
BKPhotoCell.m:
@interface BKPhotoCell() <UIScrollViewDelegate>
@property (nonatomic ,strong) UIScrollView *scrollView;
@end
@implementation BKPhotoCell
#define isPortrait [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown
#pragma mark - ScrollView Delegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
(scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
(scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
_imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
}
#pragma mark - View Lifecycle
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.bounds.size.width, self.contentView.bounds.size.height)];
[self.scrollView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
[self.scrollView setContentMode:UIViewContentModeScaleAspectFit];
[self.scrollView setDelegate:self];
[self.contentView addSubview:_scrollView];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.bounds.size.width, self.contentView.bounds.size.height)];
[self.imageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
[self.scrollView addSubview:self.imageView];
}
return self;
}
- (void)prepareForReuse {
[super prepareForReuse];
NSLog(@"Prepare for reuse");
}
- (void)layoutSubviews {
[super layoutSubviews];
[self.imageView setFrame:CGRectMake(0, 0, _imageView.image.size.width, _imageView.image.size.height)];
// NSLog(@"Setting Content Size: %f, %f", _imageView.image.size.width, _imageView.image.size.height);
[_scrollView setContentSize:_imageView.image.size];
CGFloat offsetX = (_scrollView.bounds.size.width > _scrollView.contentSize.width)?
(_scrollView.bounds.size.width - _scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (_scrollView.bounds.size.height > _scrollView.contentSize.height)?
(_scrollView.bounds.size.height - _scrollView.contentSize.height) * 0.5 : 0.0;
_imageView.center = CGPointMake(_scrollView.contentSize.width * 0.5 + offsetX,
_scrollView.contentSize.height * 0.5 + offsetY);
float minimumZoomScale;
if (isPortrait) {
minimumZoomScale = _imageView.frame.size.width >= _imageView.frame.size.height ? _scrollView.frame.size.width / _imageView.frame.size.width : _scrollView.frame.size.height / _imageView.frame.size.height;
} else {
minimumZoomScale = _imageView.frame.size.width > _imageView.frame.size.height ? _scrollView.frame.size.width / _imageView.frame.size.width : _scrollView.frame.size.height / _imageView.frame.size.height;
}
[self.scrollView setMinimumZoomScale:minimumZoomScale];
[self.scrollView setMaximumZoomScale:minimumZoomScale * 2];
[self.scrollView setZoomScale:minimumZoomScale];
}
答案 0 :(得分:2)
如果您使用的是iOS7
,则可能是您遇到了重用错误!
我确实有同样的问题,它在iOS6.1
和iOS6
上工作正常,但只要它在iOS7
(最终)上启动,单元格就永远不会被重用!
我没有修复,我正在尝试创建自己的重用逻辑。
编辑:
我有一些工作,所以你需要从布局中保存属性(如果你使用它可能会覆盖FlowLayout
)。
然后在
- (void)collectionView:(UICollectionView *)collectionView
didEndDisplayingCell:(UICollectionViewCell *)cell
forItemAtIndexPath:(NSIndexPath *)indexPath
将您的单元格保存为NSMutableArray
。
in
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
检查数组中的单元格并应用属性,例如:
UICollectionViewCell *cell;
if (![_removedCells count]) {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
forIndexPath:indexPath];
} else {
cell = [_removedCells lastObject];
[_removedCells removeLastObject];
[cell prepareForReuse];
UICollectionViewLayoutAttributes* attr = [_layout getTempAttribute:indexPath];
[cell setFrame: attr.frame];
[cell applyLayoutAttributes:attr];
if (![cell superview]) {
[_collectionView addSubview:cell];
}
}
getTempAttribute 只是从position
检索我UICollectionViewCell
的先前计算的UICollectionViewLayout
,所以只需按indexPath
查找并返回{ {1}},它看起来好像工作正常UICollectionViewLayoutAttributes
reusing
- 但我无法保证任何事情; - )
Edit2:经过进一步测试后,我必须得出结论:打破 UICollectionViewCells
中的旋转,导致奇怪的布局问题!