ios - 是否可以从 uiview 获取所有 uibezerpath?

标签 ios objective-c cgcontext uibezierpath

我一直在研究,没有找到答案。

如果我使用 CGGontext 将其绘制到 View 中,是否可以从 UIView 中获取所有 UIBezierPath? (如果是,你能给我一个想法吗?) UIBezierPath 来自用户输入,所以如果用户绘制了很多 UIBezierPath,我需要所有这些路径并将其保存到 .svg 文件中。

最佳答案

这是一个更好的工作示例,在测试了我在评论中给出的一些答案之后,这将返回一组 shapelayer 或图层,具体取决于您要查找的内容:

CAShapeLayer * firstNameCorners = [CAShapeLayer layer];
[firstNameCorners setPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 196.75, 44.0) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerTopLeft cornerRadii:(CGSize){2.5, 2.5}].CGPath];
[[self.view layer] addSublayer:firstNameCorners];

NSMutableArray *this = [[NSMutableArray alloc] init];

for (CALayer * rd in self.view.layer.sublayers) {
    if ([rd isKindOfClass:[CAShapeLayer class]]) {
        [this addObject:rd];
        NSLog(@"this is a layer: %@", rd);
    }
}
NSLog(@"this is an Array of Shapes: %@", this);

CAShapeLayer 也可以只存储一条线,不管这条线有多复杂,如果它来自 UIBezierPath 并且你将它存储在你正在绘制的 UIView 的 subLayers 中,这个对象可以存储它。事实上,为了进一步扩展这一点,为了您的目的,请参阅以下内容,这将返回 CGPath,根据您的问题,这就是您想要的:
CAShapeLayer * firstNameCorners = [CAShapeLayer layer];
[firstNameCorners setPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 96.75, 44.0) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerTopLeft cornerRadii:(CGSize){2.5, 2.5}].CGPath];
[[self.view layer] addSublayer:firstNameCorners];

NSMutableArray *this = [[NSMutableArray alloc] init];

for (CALayer * rd in self.view.layer.sublayers) {
    if ([rd isKindOfClass:[CAShapeLayer class]]) {
        [this addObject:rd];
        CAShapeLayer * rf = (CAShapeLayer*)rd;
        NSLog(@"this is a layer: %@", rf.path);
        CGRect pathBounds = CGPathGetBoundingBox(rf.path);
        NSLog(@"this is this boundingBox: origin.X: %f, origin.X: %f, size.Width: %f, size.Height: %f", pathBounds.origin.x, pathBounds.origin.y, pathBounds.size.width, pathBounds.size.height);
    }
}
NSLog(@"this is an Array of Shapes: %@", this);

而且,如果您想走得更远,那么这可以存储 CGRect 坐标,而且,这将向您展示如何检索和使用这些坐标:
CAShapeLayer * firstNameCorners = [CAShapeLayer layer];
[firstNameCorners setPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 196.75, 44.0) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerTopLeft cornerRadii:(CGSize){2.5, 2.5}].CGPath];
[[self.view layer] addSublayer:firstNameCorners];

NSMutableArray *this = [[NSMutableArray alloc] init];

NSMutableArray *that = [[NSMutableArray alloc] init];

for (CALayer * rd in self.view.layer.sublayers) {
    if ([rd isKindOfClass:[CAShapeLayer class]]) {
        [this addObject:rd];
        CAShapeLayer * rf = (CAShapeLayer*)rd;
        NSLog(@"this is a layer: %@", rf.path);
        CGRect pathBounds = CGPathGetBoundingBox(rf.path);
        [that addObject:[NSValue valueWithCGRect:pathBounds]];
        NSLog(@"this is this boundingBox: origin.X: %f, origin.X: %f, size.Width: %f, size.Height: %f", pathBounds.origin.x, pathBounds.origin.y, pathBounds.size.width, pathBounds.size.height);
    }
}

现在,结束,这是对 https://github.com/erica/iOS-6-Cookbook 的改编。 ,这是为了展示我对 UIBezierPath 的绘制的完整解构:
#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]

-(void)showPaths
{
    CAShapeLayer * firstNameCorners = [CAShapeLayer layer];
    [firstNameCorners setPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 196.75, 44.0) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerTopLeft cornerRadii:(CGSize){2.5, 2.5}].CGPath];
    [[self.view layer] addSublayer:firstNameCorners];

    NSMutableArray *this = [[NSMutableArray alloc] init];

    NSMutableArray *that = [[NSMutableArray alloc] init];

    for (CALayer * rd in self.view.layer.sublayers) {
        if ([rd isKindOfClass:[CAShapeLayer class]]) {
            [this addObject:rd];
            CAShapeLayer * rf = (CAShapeLayer*)rd;
            NSLog(@"this is a layer: %@", rf.path);
            CGRect pathBounds = CGPathGetBoundingBox(rf.path);
            [that addObject:[NSValue valueWithCGRect:pathBounds]];

            CGMutablePathRef p3 = CGPathCreateMutableCopy(rf.path);
            NSArray *p3points = [self pointsFromCGPath:p3];
            for (NSValue *point in p3points) {
                NSLog(@"path element in p3: %@", NSStringFromCGPoint(point.CGPointValue));
            }
            NSLog(@"this is this boundingBox: origin.X: %f, origin.X: %f, size.Width: %f, size.Height: %f", pathBounds.origin.x, pathBounds.origin.y, pathBounds.size.width, pathBounds.size.height);
        }
    }
}

void getPointsFromBezier(void *info, const CGPathElement *element)
{
    NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;

    // Retrieve the path element type and its points
    CGPathElementType type = element->type;
    CGPoint *points = element->points;

    switch (type) {
        case kCGPathElementMoveToPoint:
            NSLog(@"MoveToPoint (%3.2f, %3.2f", points->x, points->y);
            break;
        case kCGPathElementAddLineToPoint:
            NSLog(@"AddLineToPoint (%3.2f, %3.2f)", points->x, points->y);
            break;
        case kCGPathElementAddQuadCurveToPoint:
            NSLog(@"AddQuadCurveToPoint (%3.2f, %3.2f), (%3.2f, %3.2f)", points->x, points->y, points[1].x, points[1].y);
            break;
        case kCGPathElementAddCurveToPoint:
            NSLog(@"AddCurveToPoint (%3.2f, %3.2f), (%3.2f, %3.2f), (%3.2f, %3.2f)", points->x, points->y, points[1].x, points[1].y, points[2].x, points[2].y);
            break;
        case kCGPathElementCloseSubpath:
            NSLog(@"CloseSubpath (%3.2f, %3.2f)", points->x, points->y);
            break;
        default:
            NSLog(@"unknown");
            break;
    }

    // Add the points if they're available (per type)
    if (type != kCGPathElementCloseSubpath)
    {
        [bezierPoints addObject:VALUE(0)];
        if ((type != kCGPathElementAddLineToPoint) &&
            (type != kCGPathElementMoveToPoint))
            [bezierPoints addObject:VALUE(1)];
    }
    if (type == kCGPathElementAddCurveToPoint)
        [bezierPoints addObject:VALUE(2)];
}

- (NSArray *)pointsFromCGPath:(CGPathRef)path
{
    NSMutableArray *points = [NSMutableArray array];
    CGPathApply(path, (__bridge void *)points, getPointsFromBezier);
    return points;
}

输出将记录到控制台,我们开始时存储在 CAShapeLayer 中的所有路径,输出太大太乱,无法在此处发布,但它的开头如下所示:

[30146:2680987] MoveToPoint (103.82, 100.00

[30146:2680987] AddLineToPoint (296.75, 100.00)

[30146:2680987] AddLineToPoint (296.75, 144.00)

[30146:2680987] AddLineToPoint (103.82, 144.00)

[30146:2680987] AddCurveToPoint (102.72, 144.00), (102.17, 144.00), (101.67, 143.84)

[30146:2680987] AddLineToPoint (101.58, 143.81)

[30146:2680987] AddCurveToPoint (100.93, 143.58), (100.42, 143.07), (100.19, 142.42)

[30146:2680987] AddCurveToPoint (100.00, 141.83), (100.00, 141.28), (100.00, 140.18)

[30146:2680987] AddLineToPoint (100.00, 103.82)

[30146:2680987] AddCurveToPoint (100.00, 102.72), (100.00, 102.17), (100.16, 101.67)

[30146:2680987] AddLineToPoint (100.19, 101.58)

[30146:2680987] AddCurveToPoint (100.42, 100.93), (100.93, 100.42), (101.58, 100.19)

[30146:2680987] AddCurveToPoint (102.17, 100.00), (102.72, 100.00), (103.82, 100.00)

[30146:2680987] AddLineToPoint (103.82, 100.00)

[30146:2680987] path element in p3: {103.8216625, 100}

[30146:2680987] path element in p3: {296.75, 100}

[30146:2680987] path element in p3: {296.75, 144}

[30146:2680987] path element in p3: {103.8216625, 144}

[30146:2680987] path element in p3: {102.72123239404632, 144}

[30146:2680987] path element in p3: {102.17101736015751, 144}

关于ios - 是否可以从 uiview 获取所有 uibezerpath?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32108808/

相关文章:

ios - 无法将类型 '(_) -> ()' 的值转换为预期的参数类型 '((Bool, Error?) -> Void)?'

ios - UICollectionView:组合布局禁用预取?

ios - 从 webservice 获取 unicode 字符并在 ios 应用程序中显示它们

iphone - 有没有好的开源 iOS 应用程序模板?

ios - CGlayer 绘图性能低下

objective-c - CGContextStrokePath(context) 崩溃。为什么?

ios - 我可以创建一个完全透明的 UIView 来接收触摸吗?

ios - 我想在我的 ios 项目中识别 iphone 版本

objective-c - 为什么 CGLayers 不混合?

iPhone Quartz - 从其他类调用绘图方法