实施类似下面设计的最佳方法是什么?
一些事情:
我倾向于UICollectionView,但我并不完全确定如何使用"级别单元格。"其中一种方法可能是将水平图像分成四个并在每个单元格上绘制它们?但是,我不确定这是否是最佳解决方案。
更多信息:
答案 0 :(得分:8)
一种方法是使用具有2种不同类型细胞的集合视图;一个用于圆角矩形,另一个用于带有切角的单元。在这种方法中,您所谓的“级别单元格”根本不是单元格,而是将一个单独的视图添加到集合视图中。这将允许您使用默认的UICollectionViewFlowLayout。
我在故事板中的集合视图中添加了2个不同的单元格,并为它们提供了适当的类和唯一标识符。 RDCutCornerCell
中的代码创建了圆角矩形,右下角被切掉,并且有一种方法可以根据需要旋转该形状。这是该类的代码,
#import "RDCutCornerCell.h"
#define CUT 10
#define LINEWIDTH 2
@interface RDCutCornerCell ()
@property (strong,nonatomic) CAShapeLayer *shapeLayer;
@property (strong,nonatomic) UIBezierPath *outline;
@property (nonatomic) NSInteger currentPosition;
@end
@implementation RDCutCornerCell
-(void)rotateToPosition:(NSInteger) position {
if (! self.shapeLayer) {
self.shapeLayer = [CAShapeLayer layer];
self.backgroundColor = [UIColor clearColor];
CGRect bounds = CGRectInset(self.bounds, LINEWIDTH/2.0, LINEWIDTH/2.0);
self.outline = [UIBezierPath bezierPath];
[self.outline moveToPoint:CGPointMake(bounds.origin.x + CUT, bounds.origin.y)];
[self.outline addLineToPoint:CGPointMake(bounds.origin.x + bounds.size.width - CUT, bounds.origin.y)];
[self.outline addArcWithCenter:CGPointMake(bounds.origin.x + bounds.size.width - CUT, bounds.origin.y + CUT) radius:CUT startAngle:-M_PI/2.0 endAngle:0 clockwise:YES];
[self.outline addLineToPoint:CGPointMake(bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height/2.0)];
[self.outline addLineToPoint:CGPointMake(bounds.origin.x + bounds.size.width/2.0, bounds.origin.y + bounds.size.height)];
[self.outline addLineToPoint:CGPointMake(bounds.origin.x + CUT, bounds.origin.y + bounds.size.height)];
[self.outline addArcWithCenter:CGPointMake(bounds.origin.x + CUT, bounds.origin.y + bounds.size.height - CUT) radius:CUT startAngle:M_PI/2.0 endAngle:M_PI clockwise:YES];
[self.outline addLineToPoint:CGPointMake(bounds.origin.x, bounds.origin.y + CUT)];
[self.outline addArcWithCenter:CGPointMake(bounds.origin.x + CUT, bounds.origin.y + CUT) radius:CUT startAngle:M_PI endAngle:3*M_PI/2.0 clockwise:YES];
[self.shapeLayer setStrokeColor:[UIColor blackColor].CGColor];
self.shapeLayer.fillColor = [[UIColor colorWithRed:1 green:240/255.0 blue:175/255.0 alpha:1] CGColor];
[self.shapeLayer setLineWidth:LINEWIDTH];
[self.shapeLayer setPath:self.outline.CGPath];
[self.layer addSublayer:self.shapeLayer];
}
CGFloat angle = (M_PI/2) * (position - self.currentPosition);
CGRect boundingRect = CGPathGetPathBoundingBox(self.outline.CGPath);
CGPoint center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect));
CGAffineTransform transform = CGAffineTransformIdentity;
[self.outline applyTransform:transform];
transform = CGAffineTransformTranslate(transform, center.x, center.y);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform, -center.x, -center.y);
[self.outline applyTransform:transform];
[self.shapeLayer setPath:self.outline.CGPath];
self.currentPosition = position;
}
我创建了一个简单的UIView子类来创建“级别单元格”,
@implementation DiamondView
-(void)addLayer {
self.backgroundColor = [UIColor blackColor];
self.label = [UILabel new];
self.label.numberOfLines = 2;
self.label.frame = self.bounds;
self.label.text = @"LVL\n6";
self.label.textAlignment = NSTextAlignmentCenter;
self.label.textColor = [UIColor whiteColor];
[self addSubview:self.label];
CAShapeLayer *shape = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, self.bounds.size.width*0.12 , self.bounds.size.width*0.12) cornerRadius:8];
CGRect boundingRect = CGPathGetPathBoundingBox(path.CGPath);
CGPoint center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect));
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, center.x, center.y);
transform = CGAffineTransformRotate(transform, M_PI/4.0);
transform = CGAffineTransformTranslate(transform, -center.x, -center.y);
[path applyTransform:transform];
shape.path = path.CGPath;
self.layer.mask = shape;
}
集合视图控制器设置为在您的问题中有5列单元格,但可以使用文件顶部的#defines进行更改。我有一个属性startIndexForCutCells,它确定带有切角的四个单元格的左上单元格在集合视图中的位置。
#define CELLS_ACROSS 5 // number of cells per row
#define CELL_GAP 10 // interitem spacing for the cells
@interface RDCollectionViewController ()
@property (nonatomic) NSInteger startIndexForCutCells;
@property (nonatomic) CGFloat cellWidth;
@property (strong,nonatomic) DiamondView *diamond;
@property (strong,nonatomic) NSArray *cutCellIndexes;
@end
@implementation RDCollectionViewController {
CGFloat gap;
}
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
layout.minimumInteritemSpacing = CELL_GAP;
self.cellWidth = (self.collectionView.frame.size.width - (CELLS_ACROSS - 1) * CELL_GAP)/CELLS_ACROSS;
layout.itemSize = CGSizeMake(self.cellWidth, self.cellWidth);
_startIndexForCutCells = -100;
}
-(void)setStartIndexForCutCells:(NSInteger)startIndexForCutCells {
_startIndexForCutCells = startIndexForCutCells;
self.cutCellIndexes = @[@(_startIndexForCutCells), @(_startIndexForCutCells + 1), @(_startIndexForCutCells + CELLS_ACROSS + 1), @(_startIndexForCutCells + CELLS_ACROSS)];
if (! self.diamond) {
self.diamond = [[DiamondView alloc] initWithFrame:CGRectMake(0, 0, self.cellWidth, self.cellWidth)];
[self.collectionView addSubview:self.diamond];
[self.diamond addLayer];
}
self.diamond.center = [self setCenterForIndex:self.startIndexForCutCells];
[self.collectionView reloadData];
}
-(CGPoint)setCenterForIndex:(NSInteger) index {
NSInteger column = index % CELLS_ACROSS + 1;
NSInteger row = (index/CELLS_ACROSS) + 1;
CGPoint center = CGPointMake(column*(self.cellWidth + CELL_GAP) - CELL_GAP/2 , row*(self.cellWidth + CELL_GAP) - CELL_GAP/2);
return center;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 90;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if ([self.cutCellIndexes containsObject:@(indexPath.row)]) {
RDCutCornerCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CutCell" forIndexPath:indexPath];
NSInteger position = [self.cutCellIndexes indexOfObject:@(indexPath.row)];
[cell rotateToPosition:position];
return cell;
}else{
RDRoundedSquareCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
return cell;
}
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if ((indexPath.row + 1) % CELLS_ACROSS != 0) { // don't allow pick on the last column
self.startIndexForCutCells = indexPath.row;
}
}
此代码在单击第三行中的第三个单元格后生成此结果