2016년 5월 31일 화요일

NSView Cheatsheet

기존 NSView에 관한 잡지식(?)과 기존 글들을 한데 모은 글이다. 이 글은 지속적으로 업데이트 된다.

Background Color

NSView 에는 UIView의 backgroundColor 같은 프로퍼티가 제공되지 않는다. 필요하다면 만들어 써야된다.
class SomeView: NSView {
  ...
  var backgroundColor: NSColor?

  ...

  override func drawRect(dirtyRect: NSRect) {
    // Fill Background
    if let backgroundColor = self.backgroundColor {
      backgroundColor.setFill()
      NSRectFill(dirtyRect)
    }

    super.drawRect(dirtyRect)
  }
}

Corner Radius

UIView와 비슷하게 NSView 도 layer의 cornerRadius 와 masksToBounds 값이 있어서 비슷할 거 같은데 약간의 추가작업이 더 필요하다. wantsLayer 라는 값을 켜(true) 줘야 한다.
clsss SomeView: NSView {
  override init(frame: NSRect) {
    super.init(frame: frame)

    // Makes Round Corner
    self.wantsLayer = true
    self.layer!.cornerRadius = 10
    self.layer!.masksToBounds = true
  }
  ...
}

Flipped Coordinate System

기본적으로 Cocoa의 좌표계는 그래프 좌표계인데 이건 iOS(UIKit)과는 반대다. 이를 동일하게 뒤집으려면 flipped 라는 프로퍼티를 오버라이드 해야한다.
class SomeView: NSView {
  ...
  override var flipped: Bool { return true }
  ...
}

Handle Mouse Event

NSView 에 정의되어 있는 몇 가지 마우스 이벤트 핸들러 함수를 오버라이드 하는 식으로 구현이 가능하다. 아래는 mouseDown의 예제이다.
override func mouseDown(theEvent: NSEvent) {
  let point = self.convertPoint(theEvent.locationInWindow, fromView: nil)
  ...
}
이 외에 마우스 핸들러는 아래와 같은 이름으로 구성되어 있고 인자는 모두 NSEvent 타입 하나로 동일하다.
  • mouseDown
  • mouseUp
  • mouseEntered
  • mouseExited
  • mouseDragged
  • mouseMoved: 이 녀석은 좀 특별하다. 아래 'mouseMoved() not called' 항목을 보자.

mouseMoved() not called

NSView의 mouseMoved 함수는 드래그가 아닌 상황 즉 아무런 버튼을 누르지 않은 상태로 마우스가 해당 뷰 위에서 움직이는 경우에 호출되는 녀석이다. 그런데 이 녀석은 그냥은 호출되지 않는다. 호출되길 원한다면 Tracking Area 를 추가해 줘야 한다. 아래는 특정 NSView 서브클래스에서 Tracking Area 를 추가하는 코드 예제이다.
let trackingOptions: NSTrackingAreaOptions = [ 
  .ActiveAlways, 
  .InVisibleRect, 
  .MouseEnteredAndExited, 
  .MouseMoved ]
let trackingArea = NSTrackingArea(rect: self.bounds, 
                               options: trackingOptions, 
                                 owner: self, 
                              userInfo: nil)
self.addTrackingArea(trackingArea)

댓글 없음 :