Minhao Dong Minhao Dong - 3 months ago 8
Swift Question

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

Answer

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