Drawing text over Core Graphics in Swift 3

19,585

Solution 1

Using Swift 4:

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center

let attributes = [
    NSAttributedStringKey.paragraphStyle: paragraphStyle,
    NSAttributedStringKey.font: UIFont.systemFont(ofSize: 12.0),
    NSAttributedStringKey.foregroundColor: UIColor.blue
]

let myText = "HELLO"
let attributedString = NSAttributedString(string: myText, attributes: attributes)

let stringRect = CGRect(x: W/2 - 50, y: border, width: 100, height: H)
attributedString.draw(in: stringRect)

For Swift 4.2, change the above attributes to:

let attributes: [NSAttributedString.Key : Any] = [
    .paragraphStyle: paragraphStyle,
    .font: UIFont.systemFont(ofSize: 12.0),
    .foregroundColor: UIColor.blue
]

Solution 2

Swift 3.0 : to draw text

   func drawMyText(myText:String,textColor:UIColor, FontName:String, FontSize:CGFloat, inRect:CGRect){

     let textFont = UIFont(name: FontName, size: FontSize)!
    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
        ] as [String : Any]

    myText.draw(in: inRect, withAttributes: textFontAttributes)
}

call this function , below is e.g.

let _rect = CGRect(x: 40, y: 100, width: 40, height: 40)

 drawMyText(myText: "Hello", textColor: UIColor.black, FontName: "Helvetica Bold", FontSize: 11 , inRect:_rect)
Share:
19,585

Related videos on Youtube

Harry Netzer
Author by

Harry Netzer

Hiker, climber, hiking app programmer. Thank you stack overflow.

Updated on September 14, 2022

Comments

  • Harry Netzer
    Harry Netzer about 1 year

    Background: I am drawing on a UIImageView with Core Graphics. I would like to ultimately draw a text string over the core graphics drawing.

    This (hackingwithswift.com) method i used to draw the text to an image, set my imageView to that image, and then draw over with core graphics. But I want the text to overlay the core graphics drawing.

    Now I have moved to this https://stackoverflow.com/a/35574171/6337391 but it still isnt allowing me to write on top of my drawing.

    class MapViewController: UIViewController {
    
        @IBOutlet var imageView: UIImageView!
    
        func drawScale() {
            // establish 6 points to draw a little bar with
            let length = CGFloat(80.0)
            let bottom = imageView.bounds.size.height - 15.0
            let left = CGFloat(20.0)
            let top = bottom - 20.0
            let middle = top + 10.0
            let right = left + length
            let topLeft = CGPoint(x: left, y: top)
            let topRight = CGPoint(x: right, y: top)
            let bottomRight = CGPoint(x: right, y: bottom)
            let bottomLeft = CGPoint(x: left, y: bottom)
            let middleLeft = CGPoint(x: left, y: middle)
            let middleRight = CGPoint(x: right, y: middle)
    
            // draw the bar
            drawLineFrom(fromPoint: topLeft, toPoint: bottomLeft, color: UIColor.red.cgColor, width: 1.0, alias: false)
            drawLineFrom(fromPoint: topRight, toPoint: bottomRight, color: UIColor.red.cgColor, width: 1.0, alias: false)
            drawLineFrom(fromPoint: middleLeft, toPoint: middleRight, color: UIColor.red.cgColor, width: 1.0, alias: false)
    
            // draw a text string
            UIGraphicsBeginImageContext(self.imageView.frame.size)
    
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.alignment = .center
    
            let attrs = [
                NSFontAttributeName: UIFont.systemFont(ofSize: 12),
                NSParagraphStyleAttributeName: paragraphStyle,
                NSForegroundColorAttributeName: UIColor.red]
    
            let scaleString = "45 feet"
            scaleString.draw(at: CGPoint(x: 0, y: 50), withAttributes: attrs)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
        }
    
        /* Stroke a line between two CGPoints. Color, width, anti-alias options. */
        func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint, color: CGColor, width: CGFloat, alias: Bool) {
            // 1
            UIGraphicsBeginImageContext(self.imageView.frame.size)
            let context = UIGraphicsGetCurrentContext()!
            context.setShouldAntialias(alias)
            self.imageView.image?.draw(in: CGRect(x: 0, y: 0, width: self.imageView.frame.size.width, height: self.imageView.frame.size.height))
    
            // 2
            context.move(to: fromPoint)
            context.addLine(to: toPoint)
    
            // 3
            context.setLineWidth(width)
            context.setStrokeColor(color)
    
            // 4
            context.strokePath()
    
            // 5
            self.imageView.image = UIGraphicsGetImageFromCurrentImageContext()
            self.imageView.alpha = 1.0
            UIGraphicsEndImageContext()
        }
    }
    

    Doesnt work. Drawing the text string completely erases the bar. If move the bar drawing code under the string drawing code, then both are visible, but of course the bar is then over the string.

  • Harry Netzer
    Harry Netzer over 6 years
    That only differs from my code in that you removed the UIGraphicsBeginImageContext(self.imageView.frame.size) . Your code does not draw any text in my case.
  • Devesh.452
    Devesh.452 over 6 years
    Put drawMyText function in uiview subclass and call it from drawrect function, please let me know if you need further help
  • Harry Netzer
    Harry Netzer over 6 years
    My problem is that drawing text erases what i drew before. In my example above, the text will appear but it completely erases the lines I drew previously. As far as I can tell, your only suggesting that I draw text in a rect rather than at a point, which is not doing anything for me.
  • William Hu
    William Hu about 5 years
    swift 4.2 NSAttributedString.Key.xxx
  • shinriyo
    shinriyo over 3 years
    Small text. I want to draw text as image size
  • Kevvv
    Kevvv over 3 years
    Can I ask what the advantages are to draw texts rather than to use the UILabel? Sorry I'm new to Swift
  • ingconti
    ingconti over 3 years
    if you are un custom views you cannot use UIlabel.