我有一个带有一些绘图的自定义NSView:
class ViewController: NSViewController {
@IBOutlet weak var mainView: LineDrawer!
var time = NSTimer()
override func viewDidLoad() {
super.viewDidLoad()
self.view.needsDisplay = true
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
class LineDrawer : NSView {
required init?(coder aDecoder : NSCoder) {
super.init(coder: aDecoder)
}
var lastPt : CGPoint!
var newPt : CGPoint!
var tmp = CGPoint()
override func viewWillDraw() {
super.viewWillDraw()
lastPt = newPt
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
self.needsDisplay = true
NSColor.redColor().set()
var newLinear = NSBezierPath()
newLinear.moveToPoint(NSMakePoint(newPt.x, newPt.y))
newLinear.lineToPoint(NSMakePoint(tmp.x, tmp.y))
newLinear.lineWidth = 1
newLinear.stroke()
println(1)
}
override func mouseDown(theEvent: NSEvent) {
super.mouseDown(theEvent)
let location = theEvent.locationInWindow
lastPt = theEvent.locationInWindow
tmp = lastPt
}
override func mouseDragged(theEvent: NSEvent) {
super.mouseDragged(theEvent)
newPt = theEvent.locationInWindow
self.drawRect(self.frame)
tmp = newPt
}
}
它可以工作,但只有在隐藏并将窗口带回后才显示线条。我正在寻找用updateTheView
函数编写的代码,以便在每次激活mouseDragged时更新视图
答案 0 :(得分:2)
您需要将NSBezier stroke
放入drawRect
,而不是mouseDragged
。将mouseDragged
中的坐标保存在实例数组中,然后在drawRect
中使用Bezier进行最终绘制。
drawRect
(由某个地方的needsDisplay = true
告知或移动窗口时)。在鼠标移动例程中只存储路径。然后,当谈到绘图时,drawRect
将实际绘制线条。
class LineDrawer : NSView {
var newLinear = NSBezierPath()
override func drawRect(dirtyRect: NSRect) {
NSColor.redColor().set()
newLinear.lineWidth = 1
newLinear.stroke()
}
override func mouseDown(theEvent: NSEvent) {
super.mouseDown(theEvent)
let location = theEvent.locationInWindow
var lastPt = theEvent.locationInWindow
lastPt.x -= frame.origin.x
lastPt.y -= frame.origin.y
newLinear.moveToPoint(lastPt)
}
override func mouseDragged(theEvent: NSEvent) {
super.mouseDragged(theEvent)
var newPt = theEvent.locationInWindow
newPt.x -= frame.origin.x
newPt.y -= frame.origin.y
newLinear.lineToPoint(newPt)
needsDisplay = true
}
}
我在窗口中用普通视图测试了它。
答案 1 :(得分:1)
你很可能不会在视图上调用像setNeedsDisplay这样的方法强制重新绘制屏幕(当你再次隐藏/显示视图强制视图重新绘制时,会调用此方法)。如果您不知道视图的生命周期可以帮助您进行自定义绘图,那么这是一个有用的链接:
讨论 每当用于绘制视图对象的数据或状态发生更改时,应该向视图发送setNeedsDisplay:消息。标记为需要显示的NSView对象会在每次通过应用程序的事件循环时自动重新显示。 (查看在事件循环到来之前需要重新显示的对象当然可以立即发送到适当的display ...方法。)
答案 2 :(得分:0)
您可以使用display()
方法强制重新加载视图。
只需在主视图上调用该功能即可。
<强>文档强>
如果接收器不是不透明的,则此方法将备份视图层次结构 到第一个不透明的祖先,计算不透明的部分 接收器覆盖的祖先,并从那里开始显示。