简体   繁体   English

在osx中​​通过swift快速在NSView的图形子类内创建文本字段

[英]Create textfield programmatically inside a graph subclass of NSView with swift in osx

I am trying to add the axis text in a bar graph that I have created. 我正在尝试在创建的条形图中添加轴文本。

To do it, I used this code: 为此,我使用了以下代码:

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
}

But when calling this function inside the drawrect{} it didn't work, looks like something is missing. 但是,当在drawrect{}调用此函数时,该函数不起作用,似乎缺少了一些东西。 How can I display the axis labels? 如何显示轴标签? It should look like an excel bar chart, with title and this stuff in the axis. 它看起来应该像是excel条形图,带有标题和东西。

The bar chart looks like this, but the number of columns can be different. 条形图看起来像这样,但是列数可以不同。

bar chart in the playground 在操场上的条形图

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)

You need to add the label as a subview of the view that will contain it: 您需要将标签添加为包含标签的视图的子视图:

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

Try that and see if it works. 尝试一下,看看是否可行。 BTW, you shouldn't put this code in drawRect . 顺便说一句,您不应将此代码放在drawRect It will end up adding a new label every time the view is redrawn. 每次重新绘制视图时,最终都会添加一个新标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM