缩放 CGPath 以适应 UIVIew [英] Scale CGPath to Fit UIVIew

查看:27
本文介绍了缩放 CGPath 以适应 UIVIew的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道如何缩小或放大 CGPath 使其适合 UIView?

I need to know how I can scale down or up CGPath so it can fit UIView?

设置背景颜色为黄色,以便看清视图

Set the background color to yellow, To see the view clearly

self.frame = CGRectMake(0, 0, 181, 154);
self.backgroundColor = [UIColor yellowColor];

绘制 CAShapeLayer

Draw CAShapeLayer

CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = aPath;

shape.strokeColor = [[UIColor blueColor] CGColor];
shape.lineWidth = 5;
shape.fillColor = [[UIColor clearColor] CGColor];

[self.layer addSublayer:shape];

然后我得到这个:

我想要的是这个:

谢谢开发者:)

推荐答案

我假设您想要完全填充(不扭曲)形状以适合您的视图.我还假设您已经有一个带有路径的形状图层,因为问题被标记为 CAShapeLayer.

I'm assuming that you want to completely fill (without distorting) the shape to fit the view you. I'm also assuming that you have a shape layer with the path already, since the question is tagged CAShapeLayer.

在这种情况下,您将获得形状图层路径的边界框并计算适用于路径的适当比例因子.

In this case you would get the bounding box of the shape layers path and calculate the appropriate scale factor to apply to the path.

根据形状的纵横比和它应该适合的视图,宽度或高度将决定比例因子.

Depending on the aspect ratio of the shape and the view it is supposed to fit it will either be the widths or heights that determine the scale factor.

获得比例因子后,您将创建一个变换以应用于路径.由于路径可能不是从 (0,0) 开始,您还可以将变换中的路径转换(移动)到边界框原点.

Once you have the scale factor you will create a transform to apply to the path. Since the path may not start at (0,0) you also translate (move) the path in the transform to the bounding boxes origin.

如果您希望新路径位于视图的中心,您需要计算移动它的量.如果您不需要该代码,您可以将其注释掉,但我也将其包含在内,供其他阅读此答案的人使用.

If you want the new path to be in the center of the view you need to calculate how much to move it. You can comment out that code if you don't need it but I included it for other people reading this answer as well.

最后你有了一个新路径,所以你要做的就是创建一个新的形状图层,分配路径,适当地设置样式并将其添加到视图中.

Finally you have a new path so all you have to do is to create a new shape layer, assign the path, style it appropriately and add it to the view.

// I'm assuming that the view and original shape layer is already created
CGRect boundingBox = CGPathGetBoundingBox(shapeLayer.path);

CGFloat boundingBoxAspectRatio = CGRectGetWidth(boundingBox)/CGRectGetHeight(boundingBox);
CGFloat viewAspectRatio = CGRectGetWidth(viewToFitIn.frame)/CGRectGetHeight(viewToFitIn.frame);

CGFloat scaleFactor = 1.0;
if (boundingBoxAspectRatio > viewAspectRatio) {
    // Width is limiting factor
    scaleFactor = CGRectGetWidth(viewToFitIn.frame)/CGRectGetWidth(boundingBox);
} else {
    // Height is limiting factor
    scaleFactor = CGRectGetHeight(viewToFitIn.frame)/CGRectGetHeight(boundingBox);
}


// Scaling the path ...
CGAffineTransform scaleTransform = CGAffineTransformIdentity;
// Scale down the path first
scaleTransform = CGAffineTransformScale(scaleTransform, scaleFactor, scaleFactor);
// Then translate the path to the upper left corner
scaleTransform = CGAffineTransformTranslate(scaleTransform, -CGRectGetMinX(boundingBox), -CGRectGetMinY(boundingBox));

// If you want to be fancy you could also center the path in the view
// i.e. if you don't want it to stick to the top.
// It is done by calculating the heigth and width difference and translating
// half the scaled value of that in both x and y (the scaled side will be 0)
CGSize scaledSize = CGSizeApplyAffineTransform(boundingBox.size, CGAffineTransformMakeScale(scaleFactor, scaleFactor));
CGSize centerOffset = CGSizeMake((CGRectGetWidth(viewToFitIn.frame)-scaledSize.width)/(scaleFactor*2.0),
                                 (CGRectGetHeight(viewToFitIn.frame)-scaledSize.height)/(scaleFactor*2.0));
scaleTransform = CGAffineTransformTranslate(scaleTransform, centerOffset.width, centerOffset.height);
// End of "center in view" transformation code

CGPathRef scaledPath = CGPathCreateCopyByTransformingPath(shapeLayer.path,
                                                          &scaleTransform);

// Create a new shape layer and assign the new path
CAShapeLayer *scaledShapeLayer = [CAShapeLayer layer];
scaledShapeLayer.path = scaledPath;
scaledShapeLayer.fillColor = [UIColor blueColor].CGColor;
[viewToFitIn.layer addSublayer:scaledShapeLayer];

CGPathRelease(scaledPath); // release the copied path

在我的示例代码(和形状)中,它看起来像这样

In my example code (and shape) it looked like this

这篇关于缩放 CGPath 以适应 UIVIew的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆