| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- //
- // POBaseStyleTableViewCell.m
- // powerone
- //
- // Created by kinghai on 2018/8/3.
- // Copyright © 2018年 onecloud.ltd. All rights reserved.
- //
- #import "POBaseStyleTableViewCell.h"
- #import "BigBtn.h"
- #define DefaultCornerRadius 10 //默认视图圆角
- #define DefaultShowShadow YES //默认显示阴影
- #define DefaultShadowColor RGBACOLOR(0, 0, 0, 0.3) //默认阴影颜色
- #define DefaultShadowOpacity 0.2 //默认阴影不透明度
- #define DefaultShadowOffset CGSizeMake(0, 3) //默认阴影偏移
- #define DefaultShadowRadius 3 //默认阴影半径(并不是指阴影拐角处的圆角半径,而是阴影超出视图边界的半径)
- #define DefaultEdgeInsets UIEdgeInsetsMake(5, 8, 5, 8) //默认背景卡片距离cell的边距
- #define DefaultCorners UIRectCornerAllCorners //默认四个角都是圆角
- #define DefaultStyleViewSize CGSizeMake(SCREENWIDTH-DefaultEdgeInsets.left-DefaultEdgeInsets.right, 50-DefaultEdgeInsets.top-DefaultEdgeInsets.bottom) //默认cell的样式背景视图高宽
- #define DefaultNoShadowSide PONoShadowSideNone //默认四边都有阴影
- #define StyleBackgroundViewBackgroundColor [UIColor whiteColor] //样式背景视图的颜色
- @implementation POCellStyleDataModel
- - (instancetype)init
- {
- if (self = [super init])
- {
-
- _cornerRadius = DefaultCornerRadius;
- _showShadow = DefaultShowShadow;
- _shadowColor = DefaultShadowColor;
- _shadowOpacity = DefaultShadowOpacity;
- _shadowOffset = DefaultShadowOffset;
- _shadowRadius = DefaultShadowRadius;
- _corners = DefaultCorners;
- _styleViewSize = DefaultStyleViewSize;
- _noShadowSide = DefaultNoShadowSide;
- _cellBackgroundColor = StyleBackgroundViewBackgroundColor;
- _edgeInsets = DefaultEdgeInsets;
- }
- return self;
- }
- @end
- @implementation POCellStyleBackgroundView
- /** 如果styleModel=nil则使用默认值 */
- - (void)setupViewWithStyleModel:(POCellStyleDataModel *)styleModel
- {
- CGFloat cornerRadius = DefaultCornerRadius;
- BOOL showShadow = DefaultShowShadow;
- CGColorRef shadowColor = DefaultShadowColor.CGColor;
- CGFloat shadowOpacity = DefaultShadowOpacity;
- CGSize shadowOffset = DefaultShadowOffset;
- CGFloat shadowRadius = DefaultShadowRadius;
- UIRectCorner corners = DefaultCorners;
- CGSize styleViewSize = DefaultStyleViewSize;
- PONoShadowSide noShadowSide = DefaultNoShadowSide;
- UIColor *cellBackgroundColor = StyleBackgroundViewBackgroundColor;
-
- _styleModel = styleModel;
- if (_styleModel != nil)
- {
- cornerRadius = _styleModel.cornerRadius;
- showShadow = _styleModel.showShadow;
- shadowColor = _styleModel.shadowColor.CGColor;
- shadowOpacity = _styleModel.shadowOpacity;
- shadowOffset = _styleModel.shadowOffset;
- shadowRadius = _styleModel.shadowRadius;
- corners = _styleModel.corners;
- styleViewSize = _styleModel.styleViewSize;
- noShadowSide = _styleModel.noShadowSide;
- cellBackgroundColor = _styleModel.cellBackgroundColor?:StyleBackgroundViewBackgroundColor;
- }
-
- //解决复用cell的bug
- self.layer.mask = nil;//复用cell的时候mask还存在,所以要重新设置为nil
- NSArray *sublayerArray = [NSArray arrayWithArray:self.layer.sublayers];//因为self.layer.sublayers在执行removeFromSuperlayer时是变化的
- for (CALayer *layer in sublayerArray)
- {
- [layer removeFromSuperlayer];//移除cornerLayer和lineLayer
- }
-
- //设置圆角
- if (corners == UIRectCornerAllCorners || corners == (UIRectCornerBottomLeft|UIRectCornerBottomRight|UIRectCornerTopLeft|UIRectCornerTopRight) || cornerRadius == 0)
- {
- //四周圆角
- self.backgroundColor = cellBackgroundColor;
- self.layer.cornerRadius = cornerRadius;
- }
- else
- {
- //任意圆角
- self.backgroundColor = nil;//需要设置view的背景色为空,否则cornerLayer露出的圆角部分会显示这个颜色,阴影部分也会变成在view的边界出现
- self.layer.cornerRadius = cornerRadius;//设置任意圆角原本不用设置self.layer.cornerRadius,但是考虑到复用cell的bug,如果复用的cell原本设置了self.layer.cornerRadius=0,会导致设置部分圆角时不出现圆角
-
- CGRect viewFrame = CGRectMake(0, 0, styleViewSize.width, styleViewSize.height );
- CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:viewFrame byRoundingCorners:corners cornerRadii:CGSizeMake(cornerRadius, corners)].CGPath;
- CAShapeLayer *shapeLayer = [CAShapeLayer layer];
- shapeLayer.path = path;
-
- CALayer *cornerLayer = [CALayer layer];
- cornerLayer.frame = viewFrame;
- cornerLayer.backgroundColor = _styleModel.cellBackgroundColor.CGColor?:StyleBackgroundViewBackgroundColor.CGColor;
- cornerLayer.mask = shapeLayer;
- [self.layer addSublayer:cornerLayer];//设置self.layer.mask = shapeLayer;会导致阴影消失
- }
-
- //设置分隔线
- if ((noShadowSide & PONoShadowSideBottom) == PONoShadowSideBottom)
- {
- CGFloat lineHeight = 1;
- CGRect bounds = CGRectInset(CGRectMake(0, 0, styleViewSize.width, styleViewSize.height), 0, 0);//获取样式背景视图的size
- CALayer *lineLayer = [CALayer new];
- lineLayer.frame = CGRectMake(CGRectGetMinX(bounds), bounds.size.height-lineHeight, bounds.size.width, lineHeight);
- lineLayer.backgroundColor = UIColorFromHex(0xF3F9F5).CGColor;
- [self.layer addSublayer:lineLayer];//上部分有圆角的cell加上分隔线
- }
-
- //设置阴影
- if (showShadow && (noShadowSide & PONoShadowSideAll) != PONoShadowSideAll)
- {
- self.layer.shadowColor = shadowColor;
- self.layer.shadowOpacity = shadowOpacity;
- self.layer.shadowOffset = shadowOffset;
- self.layer.shadowRadius = shadowRadius;//不是指阴影拐角处的半径,而是指阴影超出视图边界的半径
-
- CGFloat additionMarginForShowShadow = self.layer.shadowRadius+10;//self.layer.shadowRadius是深色阴影的宽度,10是为扩散的浅色阴影而预留的范围以免无法显示阴影
- CGRect maskRect = CGRectMake(-additionMarginForShowShadow, -additionMarginForShowShadow, styleViewSize.width+2*additionMarginForShowShadow, styleViewSize.height+2*additionMarginForShowShadow);//这是包含四边阴影的范围
- if ((noShadowSide & PONoShadowSideNone) == PONoShadowSideNone)
- {
- //由于PONoShadowSide值的特殊性,只有一个位是1,为a=0001、0010、b=0100、1000等,所以比如a|b之后变成0101,(a|b)和a或者b的按位与运算等于a或b
- maskRect = CGRectZero;
- }
- else
- {
- if ((noShadowSide & PONoShadowSideTop) == PONoShadowSideTop)
- {
- maskRect.origin.y += additionMarginForShowShadow;
- maskRect.size.height -= additionMarginForShowShadow;
- }
- if ((noShadowSide & PONoShadowSideBottom) == PONoShadowSideBottom)
- {
- maskRect.size.height -= additionMarginForShowShadow;
- }
- if ((noShadowSide & PONoShadowSideLeft) == PONoShadowSideLeft)
- {
- maskRect.origin.x -= additionMarginForShowShadow;
- maskRect.size.width -= additionMarginForShowShadow;
- }
- if ((noShadowSide & PONoShadowSideRight) == PONoShadowSideRight)
- {
- maskRect.size.width -= additionMarginForShowShadow;
- }
- }
-
- if (CGRectEqualToRect(maskRect, CGRectZero) == NO)
- {
- CGPathRef path = [UIBezierPath bezierPathWithRect:maskRect].CGPath;//由于阴影超出layer的边界,所以剪切的时候要显示阴影,需要剪切rect包含阴影
- CAShapeLayer *shapeLayer = [CAShapeLayer layer];
- shapeLayer.path = path;
- self.layer.mask = shapeLayer;//将某一边的阴影剪切掉
- }
- self.layer.masksToBounds = NO;
- }
- else
- {
- //无阴影不能设置为yes
- self.layer.masksToBounds = NO;
- }
- }
- @end
- @interface POBaseStyleTableViewCell ()
- @end
- @implementation POBaseStyleTableViewCell
- - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
- {
- self.selectionStyle = UITableViewCellSelectionStyleNone;
- self.backgroundColor = [UIColor clearColor];
- _styleBackgroundView = [POCellStyleBackgroundView new];
- [self insertSubview:_styleBackgroundView atIndex:0];//不能使用self.backgroundView = _styleBackgroundView;,否则会在左滑恢复之后sbv的位置变动成和cell一样大然后才恢复为正常 —— 由于_styleBackgroundView在最底层,所以它的子视图无法响应手势
- }
- return self;
- }
- - (void)setStyleModel:(POCellStyleDataModel *)styleModel
- {
- _styleModel = styleModel;
- [self setupStyleBackgroundViewWithStyleModel:_styleModel];
- }
- - (void)setupStyleBackgroundViewWithStyleModel:(POCellStyleDataModel *)styleModel
- {
- UIEdgeInsets edgeInsets = DefaultEdgeInsets;
- if (styleModel != nil)
- {
- edgeInsets = styleModel.edgeInsets;
- }
- [_styleBackgroundView setupViewWithStyleModel:styleModel];
- [_styleBackgroundView mas_updateConstraints:^(MASConstraintMaker *make)
- {
- //不能使用mas_make,会导致之前设置的约束无法完全覆盖
- make.edges.equalTo(self).insets(edgeInsets);
- }];
- }
- - (void)setSelected:(BOOL)selected animated:(BOOL)animated
- {
- [super setSelected:selected animated:animated];
- // Configure the view for the selected state
- }
- - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
- {
- [super setHighlighted:highlighted animated:animated];
- _styleBackgroundView.backgroundColor = _styleModel.cellBackgroundColor?:StyleBackgroundViewBackgroundColor;;//当cell被点击时,子控件的背景色会消失,所以要在这个方法中重新设置背景色(如果是非全部圆角则点击时背景色不会消失,因为这个背景色是通过添加CALayer显示的)
- }
- - (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType
- {
- if(accessoryType == UITableViewCellAccessoryDisclosureIndicator)
- {
- [self po_setAccessoryType:accessoryType];
- }
- else
- {
- self.accessoryView = nil;
- [super setAccessoryType:accessoryType];
- }
- }
- @end
|