[英]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.