Search code examples
swiftparameterscgrect

How to create methods like sorted() that takes the receiver as a parameter in swift?


I wrote an extension to CGRect class. I added a method which scales the CGRect by a factor. However i don't know how to write it so that I could achieve something like

    let newFrame = view.frame.scale(by: 0.8) 

and it returns a CGRect to be set to newFrame.

What I have tried so far..

func scale(_ input: CGRect, byFactor factor: CGFloat) -> CGRect {
    let newCentre = input.centre
    let newHeight = input.size.height * factor
    let newWidth = input.size.width * factor
    let newSize = CGSize(width: newWidth, height: newHeight)
    let newRect = CGRect(centre: newCentre, size: newSize)
    return newRect
}

Any help is appreciated. Thank you!

Edit:

var upperLeft: CGPoint { return CGPoint(x: minX, y: minY) }
var centre: CGPoint { return CGPoint(x: upperLeft.x + size.width/2, y: upperLeft.y + size.height/2) }

init(centre: CGPoint, size: CGSize) {
    let upperLeft = CGPoint(x: centre.x-size.width/2, y: centre.y-size.height/2)
    self.init(origin: upperLeft, size: size)
}

What I implemented in the extension


Solution

  • The receiver in an extension of a class, struct or enum is represented by self

    extension CGRect {
    
      func scale(byFactor factor: CGFloat) -> CGRect {
        let newCentre = self.centre
        let newHeight = self.height * factor // CGRect has width and height properties
        let newWidth = self.width * factor
        let newSize = CGSize(width: newWidth, height: newHeight)
        let newRect = CGRect(centre: newCentre, size: newSize)
        return newRect
      }
    }
    

    PS: A simpler implementation of centre is

    var centre : CGPoint  {
       return CGPoint(x:CGRectGetMidX(self), y:CGRectGetMidY(self))
    }