this is almost Alexburtnik's answer   
but just to mention that UIImage.size is the logical size (in "points")   
however, CGImage.cropping() used the actual dimension (in "pixels")   
therefore, if you use a image with @2x or @3x modifiers, you will find the 
cropping is actually half or one third of the expectation.
so when you crop, you may consider multiplying the rect by the "scale" property of the image first, like the following:
func cropImage(image:UIImage, toRect rect:CGRect) -> UIImage? {
    var rect = rect
    rect.size.width = rect.width * image.scale
    rect.size.height = rect.height * image.scale
    guard let imageRef = image.cgImage?.cropping(to: rect) else {
        return nil
    }
    let croppedImage = UIImage(cgImage:imageRef)
    return croppedImage
}