我有一个自定义的UICollectionView。它看起来不错,一切都到位,但是一旦我开始滚动,一切都搞定了。单元格中的图像放错位置,尺寸错误等等。
我的自定义ViewController
看起来像这样
@implementation E5BaseDashboardViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.horizontalPadding = 10.0f;
self.verticalPadding = 10.0f;
NSManagedObjectContext *context = [[E5RestKitManager sharedInstance] threadSafeManagedObjectContext];
[context performBlockAndWait:^{
self.collectionViewData = [[E5MenuPointController sharedInstance] rootEntityMenuPointsWithDrawerPosition:E5DrawerPositionCenter andContext:context];
}];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
self.collectionView.backgroundColor = [UIColor colorWithRed:0.965f green:0.961f blue:0.953f alpha:1.00f];
// view is not hidden under navigation bar
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
// we need to move collectionView by the size of navigation bar + padding
self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.navigationController.navigationBar.frame) + 2 * self.verticalPadding, 0);
}
[self.collectionView registerClass:[E5DashboardItemCell class] forCellWithReuseIdentifier:cell_identifier];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.view addSubview:self.collectionView];
}
#pragma mark -
#pragma mark E5BaseDashboardViewController Data Source
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;
{
return [self.collectionViewData count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
E5DashboardItemCell *cell = [cv dequeueReusableCellWithReuseIdentifier:cell_identifier forIndexPath:indexPath];
E5MenuPoint *menuPoint = (E5MenuPoint *) [self.collectionViewData objectAtIndex:indexPath.row];
[cell configureCellWithMenuPoint: menuPoint];
if ([[E5MenuPointController sharedInstance] isCategoryMenuPoint: menuPoint])
{
[cell.imageView setHidden:YES];
[cell.circleBorder setHidden: YES];
}
else
{
[cell.imageView setHidden: NO];
[cell.circleBorder setHidden: NO];
}
return cell;
}
#pragma mark -
#pragma mark E5BaseDashboardViewController Delegate layout setup
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
E5MenuPoint *menuPoint = (E5MenuPoint *) [self.collectionViewData objectAtIndex:indexPath.row];
if ([[E5MenuPointController sharedInstance] isCategoryMenuPoint: menuPoint])
{
//set header cell size
CGSize cellFrame = CGSizeMake(100, 100);
cellFrame.height = (self.view.frame.size.width - 20) / 4;
cellFrame.width = self.view.frame.size.width - 20;
return cellFrame;
}
else
{
NSNumber *num = [NSNumber numberWithInt:56];
[menuPoint setCounter_notification_total: num];
//set tile cell size
CGSize cellFrame = CGSizeMake(100, 100);
cellFrame.height = (self.view.frame.size.width/2 - 15) * 1.25f;
cellFrame.width = self.view.frame.size.width/2 - 15;
return cellFrame;
}
}
#pragma mark -
#pragma mark E5BaseDashboardViewController Delegate insets, spacing
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
//set cell insets
return UIEdgeInsetsMake(10, 10, 10, 10);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
//set horizontal cell spacing
return self.horizontalPadding;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
//set vertical cell spacing
return self.verticalPadding;
}
#pragma mark -
#pragma mark E5BaseDashboardViewController Delegate selection
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[[E5MenuPointController sharedInstance] setNotificationCounterTo:0 forMenuPointWithReference:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] ref]];
[E5ActionHandler performActionOfType:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] action_type]
name:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] name]
reference:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] ref]
targetReference:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] action_target_ref]
andUrl:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] action_url]
withStoryboard:self.storyboard
andDrawerController:self.mm_drawerController
backToRoot:YES];
// track the action
if([[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] action_ref] length] > 0)
{
[[E5TrackingController sharedInstance] trackActionWithReference:[(E5MenuPoint *)[self.collectionViewData objectAtIndex:indexPath.row] action_ref]];
}
}
#pragma mark -
#pragma mark dealloc
- (void)dealloc
{
_collectionView.delegate = nil;
_collectionView.dataSource = nil;
}
@end
和自定义DashboardItemCell
类看起来像这样:
#import "E5DashboardItemCell.h"
#import "E5MenuPoint.h"
#import "E5MenuPointController.h"
@implementation E5DashboardItemCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// change to our custom selected background view
self.backgroundColor = [UIColor whiteColor];
self.layer.borderWidth = 1.0f;
self.layer.borderColor = [UIColor colorWithRed:0.925f green:0.925f blue:0.925f alpha:1.00f].CGColor;
_circleBorder = [CAShapeLayer layer];
[_circleBorder setFrame: CGRectMake(30, 20, self.frame.size.width - 60, self.frame.size.width - 60)];
[_circleBorder setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, _circleBorder.frame.size.width, _circleBorder.frame.size.height)] CGPath]];
[_circleBorder setStrokeColor:[[UIColor colorWithRed:0.910f green:0.910f blue:0.898f alpha:1.00f] CGColor]];
[_circleBorder setFillColor:[[UIColor clearColor] CGColor]];
[self.layer addSublayer:self.circleBorder];
CGFloat radius = self.circleBorder.frame.size.width/2;
CGFloat positionNotificationCenter = sqrt(radius * radius/ 2);
_notificationCircle = [CAShapeLayer layer];
[_notificationCircle setFrame:CGRectMake(self.circleBorder.frame.origin.x + radius + positionNotificationCenter - radius/4,
self.circleBorder.frame.origin.y + radius - positionNotificationCenter - radius/4,
radius/2, radius/2)];
[_notificationCircle setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, _notificationCircle.frame.size.width, _notificationCircle.frame.size.height)] CGPath]];
[_notificationCircle setStrokeColor:[[UIColor whiteColor] CGColor]];
[_notificationCircle setFillColor:[[UIColor colorWithRed:0.949f green:0.349f blue:0.196f alpha:1.00f] CGColor]];
[self.layer addSublayer:self.notificationCircle];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.circleBorder.frame.origin.x + self.circleBorder.frame.size.width/2 - self.circleBorder.frame.size.width/5,
self.circleBorder.frame.origin.y + self.circleBorder.frame.size.height/2 - self.circleBorder.frame.size.height/5,
self.circleBorder.frame.size.width/2.5,
self.circleBorder.frame.size.height/2.5)];
[self.layer addSublayer: self.imageView.layer];
_counter = [[UILabel alloc] initWithFrame:CGRectMake(_notificationCircle.frame.origin.x, _notificationCircle.frame.origin.y, _notificationCircle.frame.size.width, _notificationCircle.frame.size.height)];
_counter.textAlignment = NSTextAlignmentCenter;
[_counter setFont:[UIFont boldSystemFontOfSize:15]];
_counter.textColor = [UIColor whiteColor];
[self.layer addSublayer: self.counter.layer];
_textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[_textLabel setFont:[UIFont systemFontOfSize:15]];
_textLabel.textAlignment=NSTextAlignmentCenter;
_textLabel.numberOfLines = 0;
_textLabel.lineBreakMode = NSLineBreakByWordWrapping;
_textLabel.textColor = [UIColor colorWithRed:0.392f green:0.392f blue:0.380f alpha:1.00f];
[self.layer addSublayer: self.textLabel.layer];
}
return self;
}
- (void)configureCellWithMenuPoint:(E5MenuPoint *)menuPoint
{
BOOL isCategory = [[E5MenuPointController sharedInstance] isCategoryMenuPoint:menuPoint];
// -- text --
self.textLabel.frame = isCategory ? CGRectMake(10, 5, self.frame.size.width - 20, self.frame.size.height - 10) : CGRectMake(10, self.circleBorder.frame.origin.y + self.circleBorder.frame.size.height + 10, self.frame.size.width - 20 , self.frame.size.height - self.circleBorder.frame.size.height - self.circleBorder.frame.origin.y - 20);
self.textLabel.text = menuPoint.name;
// -- image --
if([menuPoint.image_small length] > 0 | [menuPoint.image_medium length] > 0 | [menuPoint.image_large length] > 0)
{
// show image
if (self.imageView == nil) {
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(52.5f,42.5f,40,40)];
[self addSubview:self.imageView];
}
// get the most appropriate image size for the display
NSString *imageURLAsString = [NSString string];
if([E5Utils isRetinaDisplay])
{
// retina display image priorities: medium, large, small
if([menuPoint.image_medium length] > 0)
{
imageURLAsString = menuPoint.image_medium;
}
else if([menuPoint.image_large length] > 0)
{
imageURLAsString = menuPoint.image_large;
}
else if([menuPoint.image_small length] > 0)
{
imageURLAsString = menuPoint.image_small;
}
} else {
// non-retina display image priorities: small, medium, large
if([menuPoint.image_small length] > 0)
{
imageURLAsString = menuPoint.image_small;
} else if([menuPoint.image_medium length] > 0)
{
imageURLAsString = menuPoint.image_medium;
} else if([menuPoint.image_large length] > 0)
{
imageURLAsString = menuPoint.image_large;
}
}
if([imageURLAsString length] > 0)
{
[self.imageView setImageWithURL:[NSURL URLWithString:imageURLAsString] placeholderImage:[UIImage imageNamed:@"drawer_item_icon"]];
}
}
else
{
if(self.imageView != nil)
{
// hide imageView
[self.imageView removeFromSuperview];
self.imageView = nil;
}
}
// -- counter --
[self.counter setText:[NSString stringWithFormat:@"%@", menuPoint.counter_notification_total]];
if (menuPoint.counter_notification_total.integerValue < 9)
{
[_counter setFont:[UIFont boldSystemFontOfSize:13]];
}
else if (menuPoint.counter_notification_total.integerValue > 9 && menuPoint.counter_notification_total.integerValue < 99)
{
[_counter setFont:[UIFont boldSystemFontOfSize:10]];
}
else if (menuPoint.counter_notification_total.integerValue > 99)
{
[_counter setFont:[UIFont boldSystemFontOfSize:7]];
}
BOOL showCounter = FEATURE_MENUITEM_COUNTERS && menuPoint.countWithPermanent > 0;
if (!isCategory && showCounter) {
[self.counter setHidden:NO];
[self.notificationCircle setHidden: NO];
} else {
[self.counter setHidden:YES];
[self.notificationCircle setHidden: YES];
}
}
@end
我想它与重复使用细胞有关,但我无法弄清楚是什么。这让我发疯了。有谁有任何想法可能有什么问题?
非常感谢
答案 0 :(得分:0)
搞定了。您必须为各种类型的单元格分别设置标识符。由于我只使用了一个标识符,但有两种类型的单元格,我的框架因重用一种类型的单元格而搞砸了。