使用swift函数自动更新NSView

时间:2015-01-30 15:54:18

标签: swift drawing updates nsview

我有一个带有一些绘图的自定义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时更新视图

3 个答案:

答案 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这样的方法强制重新绘制屏幕(当你再次隐藏/显示视图强制视图重新绘制时,会调用此方法)。如果您不知道视图的生命周期可以帮助您进行自定义绘图,那么这是一个有用的链接:

raywenderlich custom controls

setNeedsDisplay()

  

讨论   每当用于绘制视图对象的数据或状态发生更改时,应该向视图发送setNeedsDisplay:消息。标记为需要显示的NSView对象会在每次通过应用程序的事件循环时自动重新显示。 (查看在事件循环到来之前需要重新显示的对象当然可以立即发送到适当的display ...方法。)

Sample drawing iOS application

答案 2 :(得分:0)

您可以使用display()方法强制重新加载视图。

只需在主视图上调用该功能即可。

<强>文档

  

如果接收器不是不透明的,则此方法将备份视图层次结构   到第一个不透明的祖先,计算不透明的部分   接收器覆盖的祖先,并从那里开始显示。