图片圆角、按钮圆边,在app中经常会用到,网上实现方式也不少,这里只是做了个简单的整理。
一:利用layer实现圆角
该方式实现圆角简单,但如果在tableview或collection view的cell中大量使用圆角的话,便需要考虑其他性能上更好的实现方式了。
1代码实现:
圆型图片:
v.layer.cornerRadius = v.frame.size.width/2; //圆角弧度
v.masksToBounds = YES;//开启圆角效果
圆型图片+边框:
v.layer.cornerRadius = v.frame.size.width / 2
v.layer.borderWidth = 3.0f; //边框宽度
v.layer.borderColor = [UIColor whiteColor].CGColor; //边框颜色
v.masksToBounds = YES;
圆角图片:
v.layer.cornerRadius = 10.0f;
圆角带阴影(伪实现):
//v.layer.masksToBounds=YES;这行去掉
v.layer.cornerRadius=10;
v.layer.shadowColor=[UIColor redColor].CGColor; //阴影颜色
v.layer.shadowOffset=CGSizeMake(10, 10); //阴影偏移量
v.layer.shadowOpacity=0.5; //阴影透明度,默认0
v.layer.shadowRadius=5;
为什么说是伪实现呢,你将v.layer.cornerRadius 的值 改为v.frame.size.width / 2便可以看出
圆圈外是什么鬼?
这是因为 如果设置了masksToBounds=YES之后确实可以显示图片圆角效果,但遗憾的是设置了这个属性之后就无法设置阴影效果。因为masksToBounds=YES就意味着外边框不能显示,而阴影恰恰作为外边框绘制的,这样两个设置就产生了矛盾。
没听懂?那就要看上述方式实现圆角的原了
当绘制一张图片到图层上的时候会重新创建一个图层添加到当前图层,这样一来如果设置了圆角之后虽然底图层有圆角效果,但是子图层还是矩形,只有设置了masksToBounds为YES让子图层按底图层剪切才能显示圆角效果。同样的,有些朋友经常在网上提问说为什么使用UIImageView的layer设置圆角后图片无法显示圆角,只有设置masksToBounds才能出现效果,也是类似的问题。
知道了原因便可以找办法解决了
思路一:使用两个大小一样的图层,下面的图层负责绘制阴影,上面的图层用来显示图片。(实现代码貌似有点长,待我找找有没有更好的办法,找到了会更新到思路二中)
#define PHOTO_HEIGHT 150
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
CGPoint position= CGPointMake(160, 200);
CGRect bounds=CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT);
CGFloat cornerRadius=PHOTO_HEIGHT/2;
CGFloat borderWidth=3;
//阴影图层
CALayer *layerShadow=[[CALayer alloc]init];
layerShadow.bounds=bounds;
layerShadow.position=position;
layerShadow.cornerRadius=cornerRadius;
layerShadow.shadowColor=[UIColor redColor].CGColor;
layerShadow.shadowOffset=CGSizeMake(3, 1);
layerShadow.shadowOpacity=1;
layerShadow.borderColor=[UIColor whiteColor].CGColor;
layerShadow.borderWidth=borderWidth;
[self.view.layer addSublayer:layerShadow];
//容器图层
CALayer *layer=[[CALayer alloc]init];
layer.bounds=bounds;
layer.position=position;
layer.backgroundColor=[UIColor redColor].CGColor;
layer.cornerRadius=cornerRadius;
layer.masksToBounds=YES;
layer.borderColor=[UIColor whiteColor].CGColor;
layer.borderWidth=borderWidth;
//设置图层代理
layer.delegate=self;
//添加图层到根图层
[self.view.layer addSublayer:layer];
//调用图层setNeedDisplay,否则代理方法不会被调用
[layer setNeedsDisplay];
}
#pragma mark 绘制图形、图像到图层,注意参数中的ctx是图层的图形上下文,其中绘图位置也是相对图层而言的
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
// NSLog(@"%@",layer);//这个图层正是上面定义的图层
CGContextSaveGState(ctx);
//图形上下文形变,解决图片倒立的问题
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -PHOTO_HEIGHT);
UIImage *image=[UIImage imageNamed:@"pic4"];
//注意这个位置是相对于图层而言的不是屏幕
CGContextDrawImage(ctx, CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT), image.CGImage);
// CGContextFillRect(ctx, CGRectMake(0, 0, 100, 100));
// CGContextDrawPath(ctx, kCGPathFillStroke);
CGContextRestoreGState(ctx);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
思路二:
2xib、storyboard实现
利用runtime Attribute运行时属性:
如上图,点击+号即可添加 一个Button相关的属性,这个属性,可以是在storyboard上没有的属性,此方法类似于代码的效果,每一个属性都有与之对应的值(对象),
如数字对应的值类型是 NSNumber,如下图,填入到runtime attrite中的属性名不要写错,否则运行时会崩溃
还想设置边框颜色?Martin_wjl 的 多种方式开启StoryBoard的实时渲染(控制圆角和边框)讲的比我好,我就不献丑了,怕误人子弟。