UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

I keep getting these errors, function Swift

Forums > SwiftUI

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!

1      

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      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.