在osx中使用swift在NSView的图形子类中以编程方式创建文本字段



我正在尝试将轴文本添加到我创建的条形图中。

为此,我使用了以下代码:

func showLabel (value: String, point: CGPoint) -> NSTextField {
    let label = NSTextField(frame: NSMakeRect(point.x, point.y, 100, 100))
    label.stringValue = "Axis Value"
    label.textColor = NSColor.blueColor()
    return label
}

但是当在drawrect{}内部调用此函数时,它没有工作,看起来好像缺少了一些东西。如何显示轴标签?它应该看起来像一个excel条形图,在轴上有标题和这些东西。

条形图看起来是这样的,但列数可能不同。

操场中的条形图

import Cocoa
class MyView: NSView {
override func drawRect(rect:NSRect){
    let pathRect = NSInsetRect(self.bounds, 1, 1)
    let path = NSBezierPath(rect: pathRect)
    path.lineWidth = 1
    NSColor.whiteColor().setFill()
    NSColor.blackColor().setStroke()
    path.fill()
    path.stroke()
    let bezierPath = NSBezierPath()
    // Create a rectangle that's inset by 15% on all sides
    let drawingRect = CGRectInset(self.bounds, self.bounds.size.width * 0.15,
                                  self.bounds.size.height * 0.15);
    // Define the points that make up the drawing
    let bottomLeft = CGPointMake(CGRectGetMinX(drawingRect), CGRectGetMinY(drawingRect))
    let topRight = CGPointMake(CGRectGetMinX(drawingRect), CGRectGetMaxY(drawingRect))
    let bottomRight = CGPointMake(CGRectGetMaxX(drawingRect),
                                  CGRectGetMinY(drawingRect))

    // Start drawing
    bezierPath.moveToPoint(topRight)
    bezierPath.lineToPoint(bottomLeft)
    bezierPath.lineToPoint(bottomRight)
    // Finish drawing by closing the path
    //bezierPath.closePath()
    // Set the colors and draw them
    //NSColor.redColor().setFill()
    NSColor.blackColor().setStroke()
    //bezierPath.fill()
    bezierPath.stroke()
    // Bars
    let bezierPathBarres = NSBezierPath()

    // m'haure d'inventar algo per fer aixo
    var arrayY = [100, 200, 300, 200, 100, 200, 300, 0, 35, 100, 200, 30]
    var arrayX = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    for i in 0..<0 {
        arrayY.append(30+i)
    }
    //let arrayX = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

    // entorn de X per barres
    let numeroDeBarres: CGFloat = CGFloat(arrayY.count)
    let espaiEntreBarres:CGFloat = 0.2 // estaria be fer-ho inspectable
    let ampladaEixX = self.bounds.width * (1 - 0.30)
    let espaiOcupatDelEixPerEspaisEntreBarres = ampladaEixX * espaiEntreBarres
    let espaiOcupatDelEixPerBarres = ampladaEixX * (1 - espaiEntreBarres)
    let espaiUnaBarra = espaiOcupatDelEixPerBarres / numeroDeBarres
    let espaiUnaSeparacio = espaiOcupatDelEixPerEspaisEntreBarres / (numeroDeBarres + 1)
    //entorn de Y per barres
    let valorBarraMax: CGFloat = CGFloat(arrayY.maxElement()!)
    let alçadaEixY = self.bounds.size.height * (1 - 0.30)
    let alçadaBarraMax = alçadaEixY * 0.90
    //creem un array d'alçades
    var arrayAlçades: [CGFloat] = []
    for i in 0..<arrayY.count {
        let valorBarra = CGFloat(arrayY[i])
        arrayAlçades.append(alçadaBarraMax * valorBarra / valorBarraMax)
    }

    for i in 0..<arrayY.count {
        // Define the points that make up the drawing
        //let bottomEspaiPunt = CGPointMake(CGRectGetMinX(drawingRect), CGRectGetMinY(drawingRect))
        //let bottomBarraPuntEsquerra = CGPointMake(CGRectGetMinX(drawingRect)+(espaiUnaSeparacio + espaiUnaBarra) * CGFloat(i) + espaiUnaSeparacio, CGRectGetMinY(drawingRect))
        //let topBarraPuntEsquerra = CGPointMake(CGRectGetMinX(drawingRect)+(espaiUnaSeparacio + espaiUnaBarra) * CGFloat(i) + espaiUnaSeparacio, CGRectGetMinY(drawingRect) + arrayAlçades[i])
        //let topBarraPuntDreta = CGPointMake(CGRectGetMinX(drawingRect)+(espaiUnaSeparacio + espaiUnaBarra) * CGFloat(i) + espaiUnaBarra, CGRectGetMinY(drawingRect) + arrayAlçades[i])
        //let bottomBarraPuntDreta = CGPointMake(CGRectGetMinX(drawingRect)+(espaiUnaSeparacio + espaiUnaBarra) * CGFloat(i) + espaiUnaBarra, CGRectGetMinY(drawingRect))
        let rect = CGRect(x: CGRectGetMinX(drawingRect)+(espaiUnaSeparacio + espaiUnaBarra) * CGFloat(i) + espaiUnaSeparacio, y: CGRectGetMinY(drawingRect), width: espaiUnaBarra, height: arrayAlçades[i])
        let path = NSBezierPath(rect:rect)
        bezierPathBarres.appendBezierPath(path)
        // Start drawing
        //bezierPathBarres.moveToPoint(bottomBarraPuntEsquerra)
        //bezierPathBarres.lineToPoint(topBarraPuntEsquerra)
        //bezierPathBarres.lineToPoint(topBarraPuntDreta)
        //bezierPathBarres.lineToPoint(bottomBarraPuntDreta)
        // Adding
        let text = showLabel(String(arrayX[i]), point: CGPointMake(CGRectGetMinX(drawingRect)+(espaiUnaSeparacio + espaiUnaBarra) * CGFloat(i) + espaiUnaSeparacio + espaiUnaBarra / 2 , CGRectGetMinY(drawingRect) - 0.15 / 2 * self.bounds.size.height))
        self.addSubview(text)
        // Finish drawing by closing the path
        //bezierPathBarres.closePath()
    }
    // Set the colors and draw them
    NSColor.greenColor().setFill()
    NSColor.blackColor().setStroke()
    bezierPathBarres.fill()
    if arrayY.count<20 {
        bezierPathBarres.stroke()
    }
}

func showLabel (valor: String, point: CGPoint) -> NSTextField {
    let label = NSTextField(frame: NSMakeRect(point.x, point.y, 100, 100))
    label.stringValue = "2"
    label.textColor = NSColor.blueColor()
    return label
}
// radiate the bbox out until the hashmarks are further out than the bounds
 }
let viewRect = NSRect(x: 0, y: 0, width: 150, height: 100)
let myEmptyView = MyView(frame: viewRect)

您需要添加标签作为包含标签的视图的子视图:

let label = showLabel(...)
self.addSubview(label)

试试看是否有效。顺便说一句,你不应该把这个代码放在drawRect中。每次重新绘制视图时,都会添加一个新标签。

最新更新