缩放CGPath以适应UIVIew
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缩放CGPath以适应UIVIew相关的知识,希望对你有一定的参考价值。
我需要知道如何缩小或缩小CGPath以便它可以适合UIView?
将背景颜色设置为黄色,以清楚地查看视图
self.frame = CGRectMake(0, 0, 181, 154);
self.backgroundColor = [UIColor yellowColor];
绘制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。
在这种情况下,您将获得形状图层路径的边界框,并计算要应用于路径的适当比例因子。
根据形状的纵横比和它应该适合的视图,它将是确定比例因子的宽度或高度。
获得比例因子后,您将创建一个转换以应用于路径。由于路径可能不是从(0,0)开始,因此您还将变换中的路径转换(移动)到边界框原点。
如果您希望新路径位于视图的中心,则需要计算移动路径的数量。如果您不需要,可以注释掉该代码,但我也将其包含在阅读此答案的其他人中。
最后,您有了一条新路径,因此您所要做的就是创建一个新的形状图层,分配路径,对其进行适当的样式设置并将其添加到视图中。
// 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
在我的示例代码(和形状)中,它看起来像这样
另一答案
swift 4.0版DavidRönnqvist的回答
func resizepath(Fitin frame : CGRect , path : CGPath) -> CGPath{
let boundingBox = path.boundingBox
let boundingBoxAspectRatio = boundingBox.width / boundingBox.height
let viewAspectRatio = frame.width / frame.height
var scaleFactor : CGFloat = 1.0
if (boundingBoxAspectRatio > viewAspectRatio) {
// Width is limiting factor
scaleFactor = frame.width / boundingBox.width
} else {
// Height is limiting factor
scaleFactor = frame.height / boundingBox.height
}
var scaleTransform = CGAffineTransform.identity
scaleTransform = scaleTransform.scaledBy(x: scaleFactor, y: scaleFactor)
scaleTransform.translatedBy(x: -boundingBox.minX, y: -boundingBox.minY)
let scaledSize = boundingBox.size.applying(CGAffineTransform (scaleX: scaleFactor, y: scaleFactor))
let centerOffset = CGSize(width: (frame.width - scaledSize.width ) / scaleFactor * 2.0, height: (frame.height - scaledSize.height) / scaleFactor * 2.0 )
scaleTransform = scaleTransform.translatedBy(x: centerOffset.width, y: centerOffset.height)
//CGPathCreateCopyByTransformingPath(path, &scaleTransform)
let scaledPath = path.copy(using: &scaleTransform)
return scaledPath!
}
以上是关于缩放CGPath以适应UIVIew的主要内容,如果未能解决你的问题,请参考以下文章
在方向更改时自动缩放 UIView 以按比例缩放以适合父视图
如何缩放 UIImage 以适应 UIScrollView 的尺寸?
带有 CGPath 的 UIView 和另一个包含第一个 UIView 的 UIView。如何将第一个视图放入第二个视图?