如何按照一定的百分比值增加CGRect的大小?我应该使用某种形式的CGRectInset吗?
示例: 假设我有一个CGRect:{10, 10, 110, 110} 我想将其大小增加20%(保持相同的中心点)以获得: {0, 0, 120, 120}
示例: 假设我有一个CGRect:{10, 10, 110, 110} 我想将其大小增加20%(保持相同的中心点)以获得: {0, 0, 120, 120}
如果你喜欢的话,你可以使用CGRectInset
:
double pct = 0.2;
CGRect newRect = CGRectInset(oldRect, -CGRectGetWidth(oldRect)*pct/2, -CGRectGetHeight(oldRect)*pct/2);
为了缩小尺寸,请删除 -
。
Side note: 比 {10, 10, 100, 100}
大 20% 的 CGRect
是 {0, 0, 120, 120}
。
Edit: 如果意图是通过面积增加大小,则可以这样做(即使对于不是正方形的矩形也可以):
CGFloat width = CGRectGetWidth(oldRect);
CGFloat height = CGRectGetHeight(oldRect);
double pct = 1.2; // 20% increase
double newWidth = sqrt(width * width * pct);
double newHeight = sqrt(height * height * pct);
CGRect newRect = CGRectInset(oldRect, (width-newWidth)/2, (height-newHeight)/2);
109.5445
,这并不像假设他只是增加了边长20%那样简单明了。 - Ian MacDonald在Swift中:
func increaseRect(rect: CGRect, byPercentage percentage: CGFloat) -> CGRect {
let startWidth = CGRectGetWidth(rect)
let startHeight = CGRectGetHeight(rect)
let adjustmentWidth = (startWidth * percentage) / 2.0
let adjustmentHeight = (startHeight * percentage) / 2.0
return CGRectInset(rect, -adjustmentWidth, -adjustmentHeight)
}
let rect = CGRectMake(0, 0, 10, 10)
let adjusted = increaseRect(rect, byPercentage: 0.1)
// -0.5, -0.5, 11, 11
在ObjC中:- (CGRect)increaseRect:(CGRect)rect byPercentage:(CGFloat)percentage
{
CGFloat startWidth = CGRectGetWidth(rect);
CGFloat startHeight = CGRectGetHeight(rect);
CGFloat adjustmentWidth = (startWidth * percentage) / 2.0;
CGFloat adjustmentHeight = (startHeight * percentage) / 2.0;
return CGRectInset(rect, -adjustmentWidth, -adjustmentHeight);
}
CGRect rect = CGRectMake(0,0,10,10);
CGRect adjusted = [self increaseRect:rect byPercentage:0.1];
// -0.5, -0.5, 11, 11
这是一款受此处多个答案启发的Swift 4扩展,其中简化了计算:
extension CGRect {
func scaleLinear(amount: Double) -> CGRect {
guard amount != 1.0, amount > 0.0 else { return self }
let ratio = ((1.0 - amount) / 2.0).cgFloat
return insetBy(dx: width * ratio, dy: height * ratio)
}
func scaleArea(amount: Double) -> CGRect {
return scaleLinear(percent: sqrt(amount))
}
func scaleLinear(percent: Double) -> CGRect {
return scaleLinear(amount: percent / 100)
}
func scaleArea(percent: Double) -> CGRect {
return scaleArea(amount: percent / 100)
}
}
使用方法很简单:
rect.scaleLinear(percent: 120.0) OR (amount: 1.2)
rect.scaleArea(percent: 120.0) OR (amount: 1.2)
/// Testing
extension CGRect {
var area: CGFloat { return width * height }
var center: CGPoint { return CGPoint(x: origin.x + width/2, y: origin.y + height/2)
}
func compare(_ r: CGRect) {
let centered = center.x == r.center.x && center.y == r.center.y
print("linear = \(r.width / width), area = \(r.area / area) centered \(centered)")
}
static func ScaleTest() {
let rect = CGRect(x: 17, y: 24, width: 200, height: 100)
let percent = 122.6
rect.compare(rect.scaleLinear(percent: percent))
rect.compare(rect.scaleArea(percent: percent))
}
}
CGRectInset
是可行的:CGRect someRect = CGRectMake(10, 10, 100, 100);
someRect = CGRectInset(someRect, someRect.size.width * -0.2, someRect.size.height * -0.2);
scaleX
。 let dx = rectWidth*scaleX
let dy = rectHeight*scaleX
let rectangle = CGRect(x: rectX,
y: rectY,
width: rectWidth,
height: rectHeight).insetBy(dx: -dx, dy: -dy)
使用Swift,您可以使用扩展保留中心点(相对于源矩形),并按以下方式增加/减少大小:
extension CGRect {
func centerAndAdjustPercentage(percentage p: CGFloat) -> CGRect {
let x = self.origin.x
let y = self.origin.y
let w = self.width
let h = self.height
let newW = w * p
let newH = h * p
let newX = (w - newW) / 2
let newY = (h - newH) / 2
return CGRect(x: newX, y: newY, width: newW, height: newH)
}
}
let newRect = oldRect.centerAndAdjustPercentage(percentage: 0.25)
let scale = percent / 100
let newRect = oldRect.applying(CGAffineTransform(scaleX: scale, y: scale))
请注意,这种方法也会改变矩形的 x 和 y 值。