如何将CGRect的大小增加一定的百分比值?

bra*_*ipt 18 objective-c ios cgrect swift

如何将CGRect的大小增加一定的百分比值?我应该用某种形式CGRectInset来做吗?

例:

假设我有一个CGRect: {10, 10, 110, 110}

我想将它的大小(保持相同的中心点)增加20%:

{0, 0, 120, 120}

Ian*_*ald 35

CGRectInset如果您愿意,可以使用:

double pct = 0.2;
CGRect newRect = CGRectInset(oldRect, -CGRectGetWidth(oldRect)*pct/2, -CGRectGetHeight(oldRect)*pct/2);
Run Code Online (Sandbox Code Playgroud)

要减小尺寸,请删除-s.

旁注:A CGRect{10, 10, 100, 100}现在大20%{0, 0, 120, 120}.


编辑:如果意图是按区域增加,那么这样做(即使对于非方形的矩形):

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);
Run Code Online (Sandbox Code Playgroud)


Log*_*gan 8

在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
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止,作为唯一一个服从Apple的声明的应答者+1,"你的应用程序应该避免直接读取和写入存储在CGRect数据结构中的数据.而是使用这里描述的函数来操纵矩形并检索它们的特征. "_ - https://developer.apple.com/Library/ios/documentation/GraphicsImaging/Reference/CGGeometry/index.html (2认同)
  • Apple的声明很愚蠢.无论如何,我更新了我的答案以符合它.:/ (2认同)

rma*_*ddy 6

当然,使用CGRectInset作品:

CGRect someRect = CGRectMake(10, 10, 100, 100);
someRect = CGRectInset(someRect, someRect.size.width * -0.2, someRect.size.height * -0.2);
Run Code Online (Sandbox Code Playgroud)


use*_*529 6

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法很简单:

rect.scaleLinear(percent: 120.0)  OR (amount: 1.2)
rect.scaleArea(percent: 120.0)  OR (amount: 1.2)
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣尝试我的测试方法:

/// 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))
    }
}
Run Code Online (Sandbox Code Playgroud)