今日接到一个需求,UI设计图如下:
以正常的逻辑思维,没一个卡片应该是一个section,上面的日期和钱数,应该是section头,下面有一个距离卡片底部8像素高度的白色区域,应该为section尾。里面为该section对应的cell列表。
但是问题来了,我们可以很方便的给section Header加阴影,但是如何将Seciton作为一个整体来加阴影呢?
我最初的做法是,将一个卡片当做一个view,里面的列表用自定制的Button来实现,通过For循环来依次创建Button进行布局。
- 好处是:UI方面可以很轻松的实现卡片的阴影效果;
- 坏处是:cell内的Button个数不固定,如果条数多的画会特别容易卡,而且在快速滑动的时候,可以看到卡片有卡顿的现象。
基于上述原因,我改用UIBezierPath指定阴影的路径来实现卡片效果。
但是section头部和尾部,我分别可以指定上左右和下左右的阴影路径,但是对于列表,因为UIBezierPath只能画一条连续的线,无法单独指定左边和右边的路径,如果我通过把上下的阴影写在view内部,这样展示的时候看起来没有上下阴影,但是滑动的时候,每个cell都有了边框。而且这样组装起来的阴影,看起来不是特别的平滑,故又弃之!
最后,安卓同事点醒了我,可以通过渐变view来做阴影呀!
- 1、section头部分,分别在上,左,右添加了一个透明的view,通过设置View的背景色来达到阴影效果。
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(2, 4, 6, 48)];
[view addSubview:leftView];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = leftView.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor, nil];
gradient.startPoint = CGPointMake(0, 0);
gradient.endPoint = CGPointMake(1, 0);
[leftView.layer addSublayer:gradient];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(kScreenWidth - 8, 4, 6, 48)];
[view addSubview:rightView];
CAGradientLayer *gradientR = [CAGradientLayer layer];
gradientR.frame = rightView.bounds;
gradientR.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradientR.startPoint = CGPointMake(0, 0);
gradientR.endPoint = CGPointMake(1, 0);
[rightView.layer addSublayer:gradientR];
UIView *topV = [[UIView alloc] initWithFrame:CGRectMake(6, 0, kScreenWidth - 12, 4)];
[view addSubview:topV];
CAGradientLayer *gradientT = [CAGradientLayer layer];
gradientT.frame = topV.bounds;
gradientT.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradientT.startPoint = CGPointMake(0, 1);
gradientT.endPoint = CGPointMake(0, 0);
[topV.layer addSublayer:gradientT];
- 2、section尾部分同上,设置下,左,右渐变背景色
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(2, 0, 6, 8)];
[view addSubview:leftView];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = leftView.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradient.startPoint = CGPointMake(1, 0);
gradient.endPoint = CGPointMake(0, 0);
[leftView.layer addSublayer:gradient];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(kScreenWidth - 8, 0, 6, 8)];
[view addSubview:rightView];
CAGradientLayer *gradientR = [CAGradientLayer layer];
gradientR.frame = rightView.bounds;
gradientR.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradientR.startPoint = CGPointMake(0, 0);
gradientR.endPoint = CGPointMake(1, 0);
[rightView.layer addSublayer:gradientR];
UIView *bottomV = [[UIView alloc] initWithFrame:CGRectMake(6, 8, kScreenWidth - 12, 4)];
[view addSubview:bottomV];
CAGradientLayer *gradientB = [CAGradientLayer layer];
gradientB.frame = bottomV.bounds;
gradientB.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradientB.startPoint = CGPointMake(0, 0);
gradientB.endPoint = CGPointMake(0, 1.0);
[bottomV.layer addSublayer:gradientB];
- 3、cell部分,设置左右两个方向的阴影
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(2, 0, 6, 72)];
[self addSubview:leftView];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = leftView.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradient.startPoint = CGPointMake(1, 0);
gradient.endPoint = CGPointMake(0, 0);
[leftView.layer addSublayer:gradient];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(kScreenWidth - 8, 0, 6, 72)];
[self addSubview:rightView];
CAGradientLayer *gradientR = [CAGradientLayer layer];
gradientR.frame = rightView.bounds;
gradientR.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.12].CGColor,
(id)[UIColor colorWithRed:(0/255.0) green:(0/255.0) blue:(0/255.0) alpha:0.0].CGColor, nil];
gradientR.startPoint = CGPointMake(0, 0);
gradientR.endPoint = CGPointMake(1, 0);
[rightView.layer addSublayer:gradientR];
这里需要注意的是:
- 1、每个左右渐变View的宽度需要一致。
- 2、上下渐变view长度可以稍微长一点点,这样做出来边角也有阴影的效果。
- 3、所有的渐变颜色设置需要保持一致,否则做出来的阴影会不平滑。
- 4、startPoint和endPoint代表的view的渐变方向。只有0和1两个值。例如如果x从1到0,则代表从右向左渐变。
这样做也有缺点:那就是卡片的圆角处理暂未实现。如果有人有更好的方法,欢迎提出指正。谢谢!