- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想创建一个 mask 路径,其最终输出将是一个带有凹面的角。
我使用 -bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
方法创建了一个 UIBezierPath
并指定只有一个角需要圆角(在这个例子中, UIRectCornerBottomLeft
),我认为通过反转这条路径,我应该首先得到被削减的部分。
为此,我正在尝试 -bezierPathByReversingPath
但它似乎没有任何区别(有或没有因为我得到的是正常的 bezier 路径而不是反向)
这是我目前尝试过的:
UIView *vwTest = [[UIView alloc] init];
[vwTest setFrame:CGRectMake(100.0f, 100.0f, 100.0f, 100.0f)];
[vwTest setBackgroundColor:[UIColor redColor]];
[self.view addSubview:vwTest];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:vwTest.bounds
byRoundingCorners:UIRectCornerBottomLeft
cornerRadii:CGSizeMake(50.0f, 50.0f)];
//get reverse path but doesn't seem to work as I think it should
maskPath = [maskPath bezierPathByReversingPath];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setFrame:vwTest.bounds];
[maskLayer setPath:maskPath.CGPath];
[vwTest.layer setMask:maskLayer];
[vwTest.layer setMasksToBounds:YES];
[vwTest setNeedsDisplay];
按照下图,我想要实现的是显示 UIView
的红色部分并消除其余区域。
目前,我正在做一些像 subview 上的 subview 这样的事情,并将一个 subview 的颜色与主视图的背景颜色同步(糟透了,但至少我得到了所需的输出):
[self.view setBackgroundColor:[UIColor lightGrayColor]];
UIView *vwTest = [[UIView alloc] init];
[vwTest setFrame:CGRectMake(100.0f, 100.0f, 100.0f, 100.0f)];
[vwTest setBackgroundColor:[UIColor redColor]];
[self.view addSubview:vwTest];
UIView *vwPatch = [[UIView alloc] init];
[vwPatch setFrame:vwTest.bounds];
[vwPatch setBackgroundColor:vwTest.superview.backgroundColor];
[vwTest addSubview:vwPatch];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:vwPatch.bounds
byRoundingCorners:UIRectCornerBottomLeft
cornerRadii:CGSizeMake(50.0f, 50.0f)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setFrame:vwPatch.bounds];
[maskLayer setPath:maskPath.CGPath];
[vwPatch.layer setMask:maskLayer];
[vwPatch.layer setMasksToBounds:YES];
[vwPatch setNeedsDisplay];
有人,请给我指出正确的方向。
最佳答案
通过查看问题中的代码,我假设您希望左下角(因为您正在使用 UIRectCornerBottomLeft
)是半径为 30 的凹面。您不能将 bezierPathByReversingPath
用作一切都是从字面上反转路径,它还在文档中说:
Reversing a path does not necessarily change the appearance of the path when rendered.
编辑:
现在问题中已添加图像,OP 需要形状的倒数:
CAShapeLayer *mask = [CAShapeLayer layer];
mask.frame = view.layer.bounds;
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat radius = 50;
CGRect rect = mask.bounds;
[path moveToPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect))];
[path addLineToPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect) - radius)];
[path addArcWithCenter:CGPointMake(CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect) - radius) radius:radius startAngle:M_PI endAngle:M_PI_2 clockwise:NO];
[path closePath];
mask.path = path.CGPath;
view.layer.mask = mask;
然后路径的形状是问题中 OP 图像中的红色位。
图片发布前的回答 - 可能用于其他人
下面的代码将产生这个形状:
CGFloat cornerRadius = 30;
CGRect rect = CGRectMake(0, 0, 200, 100);
UIBezierPath *path = [UIBezierPath bezierPath];
// Draw the complete sides
[path moveToPoint:rect.origin];
[path addLineToPoint:CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect))];
[path addLineToPoint:CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect))];
// Stop short for the start of the arc
[path addLineToPoint:CGPointMake(CGRectGetMinX(rect) + cornerRadius, CGRectGetMaxY(rect))];
// Concave arc
[path addArcWithCenter:CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect)) radius:cornerRadius startAngle:0 endAngle:M_PI_2 * 3 clockwise:NO];
// Complete the path
[path closePath];
UIBezierPath
上的类别,因此您可以选择哪些角(UIRectCorner
的位掩码)和半径。
UIBezierPath+RDHConcaveCorners.h
@interface UIBezierPath (RDHConcaveCorners)
+(instancetype)bezierPathWithRoundedRect:(CGRect)rect byConcaveRoundingCorners:(UIRectCorner)corners cornerRadius:(CGFloat)radius;
@end
UIBezierPath+RDHConcaveCorners.m
@implementation UIBezierPath (RDHConcaveCorners)
+(instancetype)bezierPathWithRoundedRect:(CGRect)rect byConcaveRoundingCorners:(UIRectCorner)corners cornerRadius:(CGFloat)cornerRadius
{
CGFloat halfWidth = CGRectGetWidth(rect) / 2;
CGFloat halfHeight = CGRectGetHeight(rect) / 2;
if (cornerRadius > halfWidth || cornerRadius > halfHeight) {
cornerRadius = MIN(halfWidth, halfHeight);
}
UIBezierPath *path = [self bezierPath];
CGPoint topLeft = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
if (corners & UIRectCornerTopLeft) {
[path moveToPoint:CGPointMake(topLeft.x, topLeft.y + cornerRadius)];
[path addArcWithCenter:topLeft radius:cornerRadius startAngle:M_PI_2 endAngle:0 clockwise:NO];
} else {
[path moveToPoint:topLeft];
}
CGPoint topRight = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
if (corners & UIRectCornerTopRight) {
[path addLineToPoint:CGPointMake(topRight.x - cornerRadius, topRight.y)];
[path addArcWithCenter:topRight radius:cornerRadius startAngle:M_PI endAngle:M_PI_2 clockwise:NO];
} else {
[path addLineToPoint:topRight];
}
CGPoint bottomRight = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
if (corners & UIRectCornerBottomRight) {
[path addLineToPoint:CGPointMake(bottomRight.x, bottomRight.y - cornerRadius)];
[path addArcWithCenter:bottomRight radius:cornerRadius startAngle:M_PI_2 * 3 endAngle:M_PI clockwise:NO];
} else {
[path addLineToPoint:bottomRight];
}
CGPoint bottomLeft = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
if (corners & UIRectCornerBottomLeft) {
[path addLineToPoint:CGPointMake(bottomLeft.x + cornerRadius, bottomLeft.y)];
[path addArcWithCenter:bottomLeft radius:cornerRadius startAngle:0 endAngle:M_PI_2 * 3 clockwise:NO];
} else {
[path addLineToPoint:bottomLeft];
}
// Complete the path
[path closePath];
return path;
}
@end
关于ios - 单边角的反向 UIBezierPath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23294308/
我有两个 UIBezierPath,一个表示图像的多边形部分,另一个是要在其上绘制的路径。 我需要找到它们之间的交点,以便只有在这个交点区域内的点才会被着色。 UIBezierPath 中是否有一种方
我正在制作一个应用程序,允许用户用手指在屏幕上绘制不同的颜色。图纸是用 UIBezierPaths 绘制的,但我需要橡皮擦。我确实有一个橡皮擦,它只是一条以背景图像为颜色的路径,但这种方法会导致内存问
我想用 SceneKit 画一条贝塞尔曲线,并认为这会起作用: func drawCurvedLine() { let scene = SCNScene() let scnView =
我在设置为 iPhone (Retina 4-inch) 的模拟器中运行此代码 -(void)drawRect:(CGRect)rect { [[UIColor whiteColor]set]
我想绘制月亮,然后为月亮的阴影设置动画。但启动此代码后,我可以在动画线上看到一些故障: GIF: 为什么会发生这种情况? Playground 代码 here 更新1:此函数创建的两条路径具有不同的角
假设我们有一个 UIBezierPath...它的边界是完全正方形的...像这样: func getExponentPath(rotate180: Bool) -> UIBezierPath {
我想绘制月亮,然后为月亮的阴影设置动画。但启动此代码后,我可以在动画线上看到一些故障: GIF: 为什么会发生这种情况? Playground 代码 here 更新1:此函数创建的两条路径具有不同的角
假设我们有一个 UIBezierPath...它的边界是完全正方形的...像这样: func getExponentPath(rotate180: Bool) -> UIBezierPath {
我正在试验 UIBezierPath。我想做一个 GridView 。 NSInteger yAxisIncremental = 0; NSInteger xAxisIncremental = 0;
我需要使用bezeirPath绘制此形状: 我做了以下事情: 我创建了矩形路径。 然后我添加了五个圈子。 如下面的代码所示: let stickLayerBezeirPath = UIBezierPa
我将 Apple 文档阅读到 UIBezierPath目的。我是否正确理解它不支持相对路径? 我正在尝试将此 svg 路径转换为 UIBezierPath: // svg path m90 36c
我正在尝试制作一个球从用户画线反弹的游戏。绘制线的代码包含在下面并且可以正常工作,但是一旦球与它接触或玩家画一条新线,我将如何删除线? path = [UIBezierPath bezierPath]
我想画一条这样的路径: 这就是我写的: CGFloat radius = 50; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveT
我在 View 中有一个 UIBezierPath 。我想在单击形状时显示警报,但实际发生的情况是,不仅在我单击形状时显示警报,而且当我单击 View 中的任意位置时也会显示警报。 如何更改此代码,以
我正在尝试从圆形到带圆角的正方形制作动画。据我了解,对于流畅的动画,两条路径的点数应该相等。所以我写了一个基于多条弧构建圆的函数: private func circleShape(segmentNu
对于横向和纵向模式,是否可以将元素重置到相同的%位置(距x = 0轴的距离)?如果是的话你能告诉我怎么做吗?另外,由于我是 Swift 的新手,如果您发现任何错误的代码错误,请DO通知我以便得到更好的
我正在尝试在叠加渲染器中使用 UIBezierPath 绘制一些线条。我收到错误 CGContextSetStrokeColorWithColor: invalid context 0x0 我怀疑这是
我想圆化我的右角,但只适用于左角 let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [UIRectCorner.
我想圆化我的右角,但只适用于左角 let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [UIRectCorner.
当我尝试平移路径,将其移动到原点 {0, 0} 时,生成的路径边界错误。 (或者,我的假设是错误的)。 例如该路径给出以下边界信息: let bezier = UIBezierPath(cgPath:
我是一名优秀的程序员,十分优秀!