I keep getting these errors, function Swift

Hey guys,
I keep getting these syntax errors when trying to build my code.
The errors:

Cannot find 'uiImage' in scope
Conditional downcast to CoreFoundation type 'CGFont' will always succeed
Value of type 'CGFont' has no member 'nameToGlyph'

The code in question:

import SwiftUI

struct DrawingView: UIViewRepresentable {
    let template: String

    func makeUIView(context: Context) -> DrawingCanvas {
        let view = DrawingCanvas()
        view.loadTemplate(template)
        return view
    }

    func updateUIView(_ uiView: DrawingCanvas, context: Context) {}

    typealias UIViewType = DrawingCanvas
}

class DrawingCanvas: UIView {
    private let shapeLayer = CAShapeLayer()

    private var points = [CGPoint]()
    private var paths = [CGPath]()

    private var templatePath: CGPath?

    var isDrawingEnabled = false

    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }

    private func setup() {
        backgroundColor = .white
        shapeLayer.strokeColor = UIColor.black.cgColor
        shapeLayer.lineWidth = 5
        shapeLayer.lineCap = .round
        shapeLayer.lineJoin = .round
        layer.addSublayer(shapeLayer)
    }

   func loadTemplate(_ template: String) {
    let font = UIFont.systemFont(ofSize: bounds.size.height)
    guard let imageRef = uiImage.cgImage else {
        return
    }
    if let cgFont = font.fontDescriptor.fontAttributes[UIFontDescriptor.AttributeName(rawValue: kCTFontURLAttribute as String)] as? CGFont,
       let cgGlyph = cgFont.nameToGlyph[template] {
        if let glyphPath = CTFontCreatePathForGlyph(font, cgGlyph, nil) {
            templatePath = glyphPath
            shapeLayer.path = templatePath
        }
    }
}


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard isDrawingEnabled else { return }
        let touch = touches.first!
        let location = touch.location(in: self)
        points = [location]
        shapeLayer.path = nil
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard isDrawingEnabled else { return }
        let touch = touches.first!
        let location = touch.location(in: self)
        points.append(location)
        updateShapeLayer()
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard isDrawingEnabled else { return }
        paths.append(shapeLayer.path!)
        shapeLayer.path = templatePath
        points.removeAll()
        NotificationCenter.default.post(name: DrawingView.drawingCompleteNotification, object: nil)
    }

    private func updateShapeLayer() {
        let path = CGMutablePath()
        path.addLines(between: points)
        shapeLayer.path = path
    }

    func clear() {
        paths.removeAll()
        shapeLayer.path = templatePath
    }

    static let drawingCompleteNotification = Notification.Name("DrawingCompleteNotification")
}

The specific function:

func loadTemplate(_ template: String) {
    let font = UIFont.systemFont(ofSize: bounds.size.height)
    guard let imageRef = uiImage.cgImage else {
        return
    }
    if let cgFont = font.fontDescriptor.fontAttributes[UIFontDescriptor.AttributeName(rawValue: kCTFontURLAttribute as String)] as? CGFont,
       let cgGlyph = cgFont.nameToGlyph[template] {
        if let glyphPath = CTFontCreatePathForGlyph(font, cgGlyph, nil) {
            templatePath = glyphPath
            shapeLayer.path = templatePath
        }
    }
}

Any help would be nice, thanks!

To use UIImage, you need to import UIKit.

If you are trying to get a CGFont from a UIFont, you don’t need to cast anything. You can just do something like this:

let font = UIFont.systemFont(ofSize: 24)
if let cgFont = CGFont(font.fontName as NSString) {
    ///blah blah blah
}

CGFont does not have a method called nameToGlyph. Nor does UIFont. What are you trying to do and why do you think they have that method? Are you following a code sample from somewhere? CGFont has the method name(for:) that “Returns the glyph name of the specified glyph in the specified font.” But that goes the other direction than what you seem to be looking for. Then there’s getGlyphWithGlyphName(name:), which looks maybe more like what you want.

1 Like