18

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.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Harry Netzer
  • 312
  • 1
  • 2
  • 17
  • Could you create your text in a CATextLayer and add it to the image view? –  Feb 28 '17 at 03:56
  • What do you mean by "I am drawing on a UIImageView with Core Graphics", and under what class are you running your code? – El Tomato Feb 28 '17 at 05:13
  • I added a little bit of contextualizing code, hope it helps. I think the answer is going to lie in Core Text, I am going to try and find a solution down that road myself. Things like [link](http://stackoverflow.com/questions/27052665/swift-playground-core-graphics-core-text-custom-view) look promising – Harry Netzer Feb 28 '17 at 15:58

2 Answers2

24

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
]
Nikolay Suvandzhiev
  • 8,465
  • 6
  • 41
  • 47
ingconti
  • 10,876
  • 3
  • 61
  • 48
4

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)
Devesh.452
  • 893
  • 9
  • 10
  • 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. – Harry Netzer Mar 26 '17 at 15:00
  • Put drawMyText function in uiview subclass and call it from drawrect function, please let me know if you need further help – Devesh.452 Mar 29 '17 at 10:36
  • 1
    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. – Harry Netzer Mar 29 '17 at 14:38
  • Small text. I want to draw text as image size – shinriyo May 25 '20 at 23:37