Kevin Wang
Kevin Wang

Reputation: 682

How do you avoid UIGraphicsGetCurrentContext() returning "nil" in Swift?

I'm trying to learn how to get rounded background highlighting via (NSAttributedString background color and rounded corners)...

So I'm following Apple's Core Text Programming Guide and basically trying to recreate all the objective-C code in Swift.

I'm running into an error with UIGraphicsGetCurrentContext() returning nil

Here's my ViewController, which gets pushed when a button gets tapped in a previous view:

import UIKit
import CoreGraphics

public class HighlightPractiveViewController: UIViewController {

  override public func viewDidLoad() {
    drawRect()
  }

  func drawRect() {

    let context: CGContext = UIGraphicsGetCurrentContext()!
    context.translateBy(x: 0, y: view.bounds.size.height)
    context.scaleBy(x: 1.0, y: -1.0)
    context.textMatrix = CGAffineTransform.identity

    let path = CGMutablePath()

    let bounds = CGRect(x: 10.0, y: 10.0, width: 200.0, height: 200.0)
    path.addRect(bounds)


    let textString = NSString(string: "Hello, World!") // CF & NS are toll-free bridged.

    let attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0)

    CFAttributedStringReplaceString(attrString, CFRangeMake(0, 0), textString)

    let rgbColorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB()
    let components: [CGFloat] = [1.0, 0.0, 0.0, 0.8]
    let red: CGColor = CGColor(colorSpace: rgbColorSpace, components: components)!

    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), kCTForegroundColorAttributeName, red)

    let framesetter = CTFramesetterCreateWithAttributedString(attrString!)
    let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, nil)

    CTFrameDraw(frame, context)
  }
}

How and where do I properly call UIGraphicsGetCurrentContext() so that it doesn't return nil?

Upvotes: 1

Views: 3941

Answers (1)

Alex Nazarov
Alex Nazarov

Reputation: 199

You don't have to implement method drawRect() inside UIViewController. You have to do it inside your custom UIView.

class MyView: UIView {

   override func draw(_ rect: CGRect) {
      super.draw(rect)

      // write what you want to implement here
   }
}

Then add your custom MyView to UIViewControl's view hierarchy.

class HighlightPractiveViewController: UIViewController {

   func viewDidLoad() {
      super.viewDidLoad() // always call super's methods

      let myView = MyView()
      view.addSubview(myView)
   }  
}

Upvotes: 2

Related Questions