Draw border around content of UIImageView

haawa answer for Swift 5

extension UIImage {
    func drawOutlie(imageKeof: CGFloat = 1.01, color: UIColor) -> UIImage? {

        let outlinedImageRect = CGRect(x: 0.0, y: 0.0,
                                   width: size.width * imageKeof,
                                   height: size.height * imageKeof)

        let imageRect = CGRect(x: size.width * (imageKeof - 1) * 0.5,
                           y: size.height * (imageKeof - 1) * 0.5,
                           width: size.width,
                           height: size.height)

        UIGraphicsBeginImageContextWithOptions(outlinedImageRect.size, false, imageKeof)

        draw(in: outlinedImageRect)

        guard let context = UIGraphicsGetCurrentContext() else {return nil}
        context.setBlendMode(.sourceIn)
        context.setFillColor(color.cgColor)
        context.fill(outlinedImageRect)
        draw(in: imageRect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }
}

Here's what I did:

I did it in Swift just to check it in playgrounds, think you can translate it to Objective-C easily:

import UIKit


func drawOutlie(#image:UIImage, color:UIColor) -> UIImage
{
  var newImageKoef:CGFloat = 1.08
  
  var outlinedImageRect = CGRect(x: 0.0, y: 0.0, width: image.size.width * newImageKoef, height: image.size.height * newImageKoef)
  
  var imageRect = CGRect(x: image.size.width * (newImageKoef - 1) * 0.5, y: image.size.height * (newImageKoef - 1) * 0.5, width: image.size.width, height: image.size.height)
  
  UIGraphicsBeginImageContextWithOptions(outlinedImageRect.size, false, newImageKoef)
  
  image.drawInRect(outlinedImageRect)
  
  var context = UIGraphicsGetCurrentContext()
  CGContextSetBlendMode(context, kCGBlendModeSourceIn)
  
  CGContextSetFillColorWithColor(context, color.CGColor)
  CGContextFillRect(context, outlinedImageRect)
  image.drawInRect(imageRect)
  
  var newImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
  
  return newImage
  
}

var imageIn = UIImage(named: "158jM")

var imageOut = drawOutlie(image: imageIn, UIColor.redColor())

So how does it work?

  1. We create clean context (aka canvas) with a bit bigger size then original image (for outline)
  2. We draw our image on whole canvas
  3. We fill that image with color
  4. We draw smaller image on top

You can change outline size changing this property : var newImageKoef:CGFloat = 1.08

Here's a result that I had in playgrounds

enter image description here

Swift 5:

extension UIImage {
    
    func drawOutlie(imageKeof: CGFloat = 0.2, color: UIColor = .white)-> UIImage? {
        let outlinedImageRect = CGRect(x: 0.0, y: 0.0, width: size.width * imageKeof, height: size.height * imageKeof)
        let imageRect = CGRect(x: self.size.width * (imageKeof - 1) * 0.5, y: self.size.height * (imageKeof - 1) * 0.5, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(outlinedImageRect.size, false, imageKeof)
        draw(in: outlinedImageRect)
        let context = UIGraphicsGetCurrentContext()
        context!.setBlendMode(.sourceIn)
        context!.setFillColor(color.cgColor)
        context!.fill(outlinedImageRect)
        draw(in: imageRect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}