Understanding Swift Syntax for a particular method

I am trying to apply a tint color on a set of UIImages that I have and I came across this neat implementation online that I am trying to understand. My question is about line 2 and line 27. Thanks in advance!


Line 2: What is the syntax in the parameters list? This is something I haven't seen before...

Line 27: This type of return statement is also new to me, I'm guessing its related to the special syntaxt in modifiedImage?



// What is the syntaxt in the parameters list? Never seen this before....
private func modifiedImage( draw: (CGContext, CGRect) -> ()) -> UIImage {
      
      // using scale correctly preserves retina images
      UIGraphicsBeginImageContextWithOptions(size, false, scale)
      let context: CGContext! = UIGraphicsGetCurrentContext()
      assert(context != nil)
      
      // correctly rotate image
      context.translateBy(x: 0, y: size.height)
      context.scaleBy(x: 1.0, y: -1.0)
      
      let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
      
      draw(context, rect)
      
      let image = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()
      return image!
   }


func tint(tintColor: UIColor) -> UIImage {
      
     // Never seen this type of return statement... maybe if in understand the private func uptop, then
     // this will make sense...
      return modifiedImage { context, rect in
         // draw black background - workaround to preserve color of partially transparent pixels
         context.setBlendMode(.normal)
         UIColor.black.setFill()
         context.fill(rect)
         
         // draw original image
         context.setBlendMode(.normal)
         context.draw(self.cgImage!, in: rect)
         
         // tint image (loosing alpha) - the luminosity of the original image is preserved
         context.setBlendMode(.color)
         tintColor.setFill()
         context.fill(rect)
         
         // mask by alpha values of original image
         context.setBlendMode(.destinationIn)
         context.draw(self.cgImage!, in: rect)
      }
   }
Accepted Answer

Line 02.

`(CGContext, CGRect) -> ()` is a closure type. You need to pass a closure taking two parameters of types `CGContext` and `CGRect`.


Line 27. to 45.

From `{ context, rect in` in line 27. to `}` in line 45. is a closure literal. It's passed to the method `modifiedImage` as `draw`.


Closures are very often used in many actual apps and you should better learn about it: Closures.

Thanks. Going to look at the link about closures you sent. How did you link that closures link by the way? Usually, if I want to attach a link I have to break the URL otherwise my question won't get posted on the forums.. Thanks again!

Some websites (*.apple.com, *.swift.org, stackoverflow.com) are whitelisted on this forum and can be posted without moderation.

Closure are a bit tricky at beginning.


The code is equivalent to this one, less compact, but which shows how it works, if that can help:


     typealias DrawClosure = (CGContext, CGRect) -> ()  
     private func modifiedImage( draw: DrawClosure) -> UIImage {
        
          // using scale correctly preserves retina images
          UIGraphicsBeginImageContextWithOptions(size, false, scale)
          let context: CGContext! = UIGraphicsGetCurrentContext()
          assert(context != nil)
        
          // correctly rotate image
          context.translateBy(x: 0, y: size.height)
          context.scaleBy(x: 1.0, y: -1.0)
        
          let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
        
          draw(context, rect)
        
          let image = UIGraphicsGetImageFromCurrentImageContext()
          UIGraphicsEndImageContext()
          return image!
     }
   
   
     func tint(tintColor: UIColor) -> UIImage {
        
          let drawClosure: DrawClosure = { context, rect in
               // draw black background - workaround to preserve color of partially transparent pixels
               context.setBlendMode(.normal)
               UIColor.black.setFill()
               context.fill(rect)
             
               // draw original image
               context.setBlendMode(.normal)
               context.draw(self.cgImage!, in: rect)
             
               // tint image (loosing alpha) - the luminosity of the original image is preserved
               context.setBlendMode(.color)
               tintColor.setFill()
               context.fill(rect)
             
               // mask by alpha values of original image
               context.setBlendMode(.destinationIn)
               context.draw(self.cgImage!, in: rect)
          }

          // Never seen this type of return statement... maybe if in understand the private func uptop, then
          // this will make sense...
          // Here, the return statement is easy to understand

          return modifiedImage(draw: drawClosure)     // In your original post, the parameter is not in parenthesis, but as a trailing closure
     }
Understanding Swift Syntax for a particular method
 
 
Q