2017년 2월 1일 수요일

NSScrollView Cheatsheet

개인적으로 NSScrollView 를 이용하면서 알게된 팁을 모아본 글이다. 이 글은 계속 업데이트 될 수 있다.

How to add Subview?

UIScrollView 를 쓸 때 처럼 addSubview() 로 뷰를 추가해도 뭔가 이상하던데 역시나 NSScrollView 는 약간 달랐다. documentView 라는 것에다 최상위 뷰 하나를 추가해 주면 간단히 뷰를 하나 추가할 수 있다.
let someContentView = SomeView(frame: ...)
scrollView.documentView = someContentView

Scroll Programmatically

코드를 이용해 스크롤을 하려고 하는 경우 NSClipView 의 scroll(to:) 메소드를 이용 할 수 있다. 즉 ScrollView 의 contentView 를 이용해먹자.
scrollView.contentView.scroll(to: NSPoint(x: 0, y: 0))

contentOffset?

UIScrollView 의 경우 contentOffset 이 제공되는데 이와 비슷한게 없다. 이 경우
scrollView.documentVisibleRect.origin
documentVisibleRect 의 origin 프로퍼티를 contentOffset 과 비슷한 용도로 쓸 수 있다.

Scroll Programmatically with Animation

위의 경우 애니메이션이 제공되지 않는데, 애니메이션을 위해서는 방법을 다르게 할 필요가 있다. 아래는 예제이다.
NSAnimationContext.beginGrouping()
NSAnimationContext.current().duration = 3.0
scrollView.contentView.animator().setBoundsOrigin(NSPoint(x: 0, y: 0))
NSAnimationContext.endGrouping()
animator 의 bound origin 을 바꾸는 방식으로 스크롤 훙내를 낼 수 있다.

Zoom

UIScrollView 와는 다르게 NSScrollView 는 zoom 이나 scale 이 아닌 magnification 이라는 용어를 사용한다.
scrollView.allowMagnification = true
scrollView.minMagnification = 0.1
scrollView.maxMagnification = 2.0
scrollView.magnification = 0.5
확대 축소 비율을 최소 0.1배 최대 2배를 설정한 상태에서 0.5배로 축소를 하는 코드이다.

Centering(?)

축소 시 내용물을 스크롤뷰 가운데에 위치하게 하고 싶다면 NSClipView 를 좀 고쳐야 한다. 아래는 NSClipView 를 상속받아서 만든 CenterClipView 클래스 코드이다.
class CenterClipView: NSClipView {

  override func constrainBoundsRect(_ proposedBounds: NSRect) -> NSRect {
    var constrainedClipViewBounds = super.constrainBoundsRect(proposedBounds)
    
    guard let documentView = self.documentView else {
      return constrainedClipViewBounds
    }
    
    let documentViewFrame = documentView.frame
    
    if documentViewFrame.width < proposedBounds.width {
      constrainedClipViewBounds.origin.x = floor((proposedBounds.width - documentViewFrame.width) / -2.0)
    }
    
    if documentViewFrame.height < proposedBounds.height {
      constrainedClipViewBounds.origin.y = floor((proposedBounds.height - documentViewFrame.height) / -2.0)
    }
    
    return constrainedClipViewBounds
  }
  
}
이후 ScrollView 의 contentView 를 위 클래스 인스턴스로 바꿔줘야 한다. 물론 스토리보드나 인터페이스 빌더에서 스크롤뷰의 클립뷰(Clip View)의 클래스 타입을 CenterClipView 로 바꿔주면 되는 쉬운 작업이다.

댓글 없음 :