【问题标题】:How can I draw text in Swift's CoreGraphics context in a UIImageView?如何在 UIImageView 的 Swift CoreGraphics 上下文中绘制文本?
【发布时间】:2022-10-16 05:48:09
【问题描述】:

我正在尝试在 Swift 的 CoreGraphics 中的 UIImageView 中为动态几何软件应用程序绘制一个字符串。我正在使用上下文图形来绘制点和线,但是当我尝试绘制文本字符串(例如,线段的长度)时,我要么没有文本(例如在这两个示例中),要么其他所有内容除了文本字符串之外,我正在绘制的内容已被删除(抱歉,我没有保存该示例)。在后一种情况下,我可以在字符串顶部绘制其他东西,但这也不是很有帮助,因为我只能绘制一个字符串(尝试绘制第二个字符串删除了第一个字符串)。

以下是两次尝试,均未绘制文本字符串:

        UIGraphicsBeginImageContext(canvas.frame.size)
        canvas.draw(CGRect(x: 0, y: 0, width: canvas.frame.width, height: canvas.frame.height))
        let context = UIGraphicsGetCurrentContext()
        let text="\(value)"
        let font=UIFont(name: "Helvetica", size: 12)!
        let text_style=NSMutableParagraphStyle()
        text_style.alignment=NSTextAlignment.center
        let text_color=UIColor.black
        let attributes=[NSAttributedString.Key.font:font, NSAttributedString.Key.paragraphStyle:text_style, NSAttributedString.Key.foregroundColor:text_color]
        let text_x=coordinates.x
        let text_y=coordinates.y
        let text_rect=CGRect(x: text_x, y: text_y, width: 100, height: font.lineHeight)
        text.draw(in: text_rect.integral, withAttributes: attributes)
        UIGraphicsEndImageContext()
    }```

```override func draw(_ canvas: UIImageView, _ isRed: Bool) {
        UIGraphicsBeginImageContext(canvas.frame.size)
        canvas.draw(CGRect(x: 0, y: 0, width: canvas.frame.width, height: canvas.frame.height))
        let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))
        let img = renderer.image { ctx in
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.alignment = .center
            let attrs = [NSAttributedString.Key.font: UIFont(name: "HelveticaNeue-Thin", size: 12)!, NSAttributedString.Key.paragraphStyle: paragraphStyle]
            let string = "\(value)"
            string.draw(with: CGRect(x: coordinates.x, y: coordinates.y, width: 100, height: 16), options: .usesLineFragmentOrigin, attributes: attrs, context: nil)
        }
    }```

I have also found a page that says something to the effect that it is impossible to draw text in a UIImageView.  However, it is hard to believe that a graphics system as mature as core graphics wouldn't allow drawing text.

【问题讨论】:

    标签: swift graphics uiimageview drawtext


    【解决方案1】:

    我正在使用核心图形在 MacOS Cocoa 中制作条形图。该程序为 SwiftUI 嵌入了一些有用的链接。您应该能够使我的代码适应您的程序。

    //  ViewController.swift
    //  Chart_test
    //
    //  Created by slareau on 2022-10-10.
    //
    
    //https://stackoverflow.com/questions/38079917/drawing-in-cocoa-swift
    //https://www.raywenderlich.com/1101-core-graphics-on-macos-tutorial
    //https://stackoverflow.com/questions/10627557/mac-os-x-drawing-into-an-offscreen-nsgraphicscontext-using-cgcontextref-c-funct
    //https://nshipster.com/cggeometry/
    //https://www.hackingwithswift.com/example-code/core-graphics/how-to-draw-a-text-string-using-core-graphics
    
    
    import Cocoa
    
    import CoreGraphics
    
    class ChartsVC: NSViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
     
            print("ChartsVC")
            let dr = Drawing(frame: NSRect(x: 50, y: 50, width: 550, height: 500))
            self.view.addSubview(dr)
       
        }
    }
        
    
    class Drawing: NSView {
        
        //var facts_list: [myfact] = [] //complete database
        //var fact_total: [Double] = [0.0, 0.0, 0.0, 0.0, 0.0]
        var fact_total: [Double] = [12454, 22365,18989, 14656, 16777]
        
        //var comm_list: [myComm] = []
        // var comm_total: [Double] = [0.0, 0.0, 0.0, 0.0, 0.0]
        var comm_total: [Double] = [8976, 14989, 13989, 12065, 15040]
        
        var Current_Year : Int = 0
        var Current_Month : Int = 0
        
        override func draw(_ dirtyRect: NSRect) {
            super.draw(dirtyRect)
            
            
            let todays_date = Date()
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy"
            Current_Year = Int(dateFormatter.string(from: todays_date))!
            
            // print ("VC60:", dateFormatter.string(from: todays_date), Current_Year!) OK
            
            
            dateFormatter.dateFormat = "MM"
            Current_Month = Int(dateFormatter.string(from: todays_date))!
            
            // Load_CommDB()
            // Load_FactDB()
            
            
            var j = 0
            while j < 5 {  // last 5 years
                print ( "VCH165:  ", Current_Year - j, fact_total[j], comm_total[j] )
                j += 1
            }
            
            
            // frame background
            myRect(x: 0, y: 0, wd: 500, ht: 400, color: NSColor.lightGray)
            
            for i in 0...4 {
                
                let factT = String(fact_total[4 - i])
                let commT = String(comm_total[4 - i])
                let diffT = String(fact_total[4 - i] - comm_total[4 - i])
                
                myRect(x: Double(50 + 80 * i) , y: 80, wd: 50, ht: Double(fact_total[4 - i]/100), color: NSColor.blue)
                myRect(x: Double(60 + 80 * i) , y: 80, wd: 50, ht: Double(comm_total[4 - i]/100), color: NSColor.orange)
                myRect(x: Double(70 + 80 * i) , y: 80, wd: 50, ht: Double((fact_total[4 - i] - comm_total[4 - i])/100), color: NSColor.green)
                mytext(txt:  factT.toCurrencyFormat(), x: Double(45 + 80 * i), y: 60)
                mytext(txt:  commT.toCurrencyFormat(), x: Double(45 + 80 * i), y: 40)
                mytext(txt:  diffT.toCurrencyFormat(), x: Double(45 + 80 * i), y: 20)
                mytext(txt:  String(Current_Year - (4 - i)), x: Double(45 + 80 * i), y: 3)
            }
            
            let context = NSGraphicsContext.current!.cgContext;
            context.beginPath()
            context.move(to: CGPoint(x: 10.0, y: 78.0))
            context.addLine(to: CGPoint(x: 420.0, y: 78.0))
            //context.setStrokeColor(red: 1, green: 0, blue: 0, alpha: 1)
            context.setStrokeColor(NSColor.black.cgColor)
            context.setLineWidth(2.0)
            context.strokePath()
            
        }
        
        func myRect( x: Double, y: Double, wd:  Double, ht :Double, color: NSColor) {
            let context = NSGraphicsContext.current!.cgContext;
            let rectangle = CGRect(x: x, y: y, width: wd, height: ht) // NSRect or CGRect work
            //context.setFillColor(NSColor.yellow.cgColor)
            context.setFillColor(color.cgColor)
            context.setStrokeColor(NSColor.black.cgColor)
            context.setLineWidth(2)
            context.addRect(rectangle)
            context.drawPath(using: .fillStroke)
            
            
        }
        
        func mytext ( txt: String,  x: Double, y: Double) {
            // let myfont = CTFontCreateWithName("Papyrus" as CFString, 12, nil)
            let myfont = CTFontCreateWithName("Arial" as CFString, 12, nil)
            let attributedString = NSAttributedString(string: txt, attributes: [NSAttributedString.Key.font: myfont])
            //  let attributedString = NSAttributedString(string: "allo le monde")
            let line = CTLineCreateWithAttributedString(attributedString)
            
            // Draw text
            if let context = NSGraphicsContext.current?.cgContext {
                context.textPosition = .init(x: x , y: y)
                
                CTLineDraw(line, context)
            }
            //https://blog.krzyzanowskim.com/2020/07/09/coretext-academy-part-1/
            //https://blog.krzyzanowskim.com/2020/07/10/coretext-swift-academy-part-2/
            //https://blog.krzyzanowskim.com/2020/07/13/coretext-swift-academy-part-3/
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多