ios 如何将 CGRect 的大小增加某个百分比值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26918886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:37:31  来源:igfitidea点击:

How can I increase the size of a CGRect by a certain percent value?

iosobjective-cswiftcgrect

提问by brandonscript

How can I increase the size of a CGRect by a certain percent value? Should I use some form of CGRectInsetto do it?

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

Example:

例子:

Assume I have a CGRect: {10, 10, 110, 110}

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

I want to increase it's size (retaining the same center point) by 20% to:

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

{0, 0, 120, 120}

{0, 0, 120, 120}

回答by Ian MacDonald

You can use CGRectInsetif you like:

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

double pct = 0.2;
CGRect newRect = CGRectInset(oldRect, -CGRectGetWidth(oldRect)*pct/2, -CGRectGetHeight(oldRect)*pct/2);

To decrease the size, remove the -s.

要减小大小,请删除-s。

Side note: A CGRectthat is 20% bigger than {10, 10, 100, 100}is {0, 0, 120, 120}.

附注:一个CGRect是比大20%{10, 10, 100, 100}{0, 0, 120, 120}



Edit: If the intention is to increase by area, then this'll do it (even for rectangles that aren't square):

编辑:如果打算按面积增加,那么这样做(即使对于不是正方形的矩形):

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);

回答by Logan

In 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

In ObjC:

在 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

回答by rmaddy

Sure, using CGRectInsetworks:

当然,使用CGRectInset作品:

CGRect someRect = CGRectMake(10, 10, 100, 100);
someRect = CGRectInset(someRect, someRect.size.width * -0.2, someRect.size.height * -0.2);

回答by gheclipse

Swift 4 extension inspired by several of the answers here with simplified calculations:

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)
    }
}

Usage is simply:

用法很简单:

rect.scaleLinear(percent: 120.0)  OR (amount: 1.2)
rect.scaleArea(percent: 120.0)  OR (amount: 1.2)

If you are interested in trying my testing methods:

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

/// 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))
    }
}

回答by ihsanberahim

I'm using CGRect > insetBy in my Swift code

我在我的 Swift 代码中使用 CGRect > insetBy

https://developer.apple.com/documentation/coregraphics/cgrect/1454218-insetby

https://developer.apple.com/documentation/coregraphics/cgrect/1454218-insetby

With this, your percent value will be the scaleXas my example.

有了这个,您的百分比值将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)
  • use positive value to scale down
  • use negative value to scale up
  • 使用正值缩小
  • 使用负值放大

回答by Nick

Using Swift you can retain the center point (relative to the source Rect) and increase/decrease the size as follows using an extension:

使用 Swift,您可以保留中心点(相对于源 Rect)并使用扩展如下增加/减少大小:

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)

回答by Taras

let scale = percent / 100
let newRect = oldRect.applying(CGAffineTransform(scaleX: scale, y: scale))

Beware that this approach also will change x and y of rectangle.

请注意,这种方法也会改变矩形的 x 和 y。