UIBezierPath的一些应用
引导页
在项目中有见到使用UIBezierPath
来做一些用户引导说明,效果大致如下图所示,参考iOS: 首次使用App时,显示半透明新手指引:
使用了UIBezierPath
的bezierPathByReversingPath方法,参照bezierPathByReversingPath,试了下,区别如下:
- (void)drawRect:(CGRect)rect {
UIBezierPath *thePath = [UIBezierPath bezierPath];
UIBezierPath *revPath = [UIBezierPath bezierPath];
[thePath appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(50,50,150,100)]];
[[UIColor redColor] set];
[revPath appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(60,60,100,100)]];
//revPath = [revPath bezierPathByReversingPath];
[thePath appendPath:revPath];
[[UIColor redColor] set];
[thePath fill];
}
注释掉revPath = [revPath bezierPathByReversingPath];
,效果如下:
取消注释revPath = [revPath bezierPathByReversingPath];
,效果如下:
下面通过一个mask来说一下UIBezierPath
在做用户引导上的应用,步骤如下:
a.在控制器的view
上添加一个imageview
,控制器的view
的背景为洋红色
b.使用UIBezierPath
创建一个圆形曲线,并做mask
CGRect rect = CGRectMake((self.imageView.frame.size.width-200) / 2, (self.imageView.frame.size.height-200) / 2, 200, 200);
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.path = path.CGPath;
self.imageView.layer.mask = shapeLayer;
做遮罩后的效果如下:
c.path之后再拼接一个矩形的曲线,如下:
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectInset(rect, 50, 50)]] ;
效果如下,貌似没什么改变的:
d.使用bezierPathByReversingPath
,使用如下的代码替换第c步的代码:
[path appendPath:[[UIBezierPath bezierPathWithRect:CGRectInset(rect, 50, 50)] bezierPathByReversingPath]];
显示效果如下:
所以,在window添加个透明的view,做一些遮罩,就可实现类似的用户引导效果
要注意的一点是,如果在控制器的viewDidLoad
方法中调用:
UIWindow *window = [[UIApplication sharedApplication].windows lastObject];
[window addSubview:bgView];
此时bgView
被控制器的view
所覆盖,如下所示(品红色为bgView
,白色为控制器的view
):
可参考KeyWindow add subView, did not shows in the front
You run into this issue, is caused by you do not know the difference between the viewDidLoad method and the viewDidAppear: method.
viewWillAppear:
Called before the view is added to the windows’ view hierarchy
viewDidAppear:
Called after the view is added to the view hierarchy
The controller’s view add to the window’s view hierarchy is betweenviewWillAppear: and viewDidAppear:, the viewDidLoad is in front of viewWillAppear:, so you can not do that. you should in viewDidAppear: add your view.
特殊形状的页面
可参考:放肆地使用UIBezierPath和CAShapeLayer画各种图形
如下:
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
CGSize finalSize = CGSizeMake(CGRectGetWidth(self.frame), 200);
CGFloat layerHeight = finalSize.height * 0.2;
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
UIBezierPath *bezier = [[UIBezierPath alloc] init];
[bezier moveToPoint:CGPointMake(0, finalSize.height - layerHeight)];
[bezier addLineToPoint:CGPointMake(0, finalSize.height - 1)];
[bezier addLineToPoint:CGPointMake(finalSize.width, finalSize.height - 1)];
[bezier addLineToPoint:CGPointMake(finalSize.width, finalSize.height - layerHeight)];
[bezier addQuadCurveToPoint:CGPointMake(0,finalSize.height - layerHeight)
controlPoint:CGPointMake(finalSize.width / 2, (finalSize.height - layerHeight) - 40)];
layer.path = bezier.CGPath;
layer.fillColor = [UIColor blackColor].CGColor;
[self.layer addSublayer:layer];
}
return self;
}
效果如下: