콘텐츠로 건너뛰기
Home » Development » Cocoa » Page 4

Cocoa

드래그 앤 드롭으로 콘텐츠 복사를 구현하기 – Cocoa, Swift

많은 코코아 관련 서적에서 복사/붙여넣기를 구현하는 다음 과정으로 드래그 앤 드롭을 소개하는데, 대부분이 어떤 이미지 뷰에 이미지를 끌어다 놓는 부분까지만 소개하고 있다. 아마도 드래그 앤 드롭 자체가 실제로는 상당히 복잡한 매커니즘이라 그런 듯 한데, 이번 글에서는 드래그 앤 드롭을 구현하기 위해서 소스 뷰와 타깃 뷰 그리고 전달되는 데이터 모델에 대해 어떤 클래스와 구현이 필요한지를 살펴보도록 하겠다.
더 보기 »드래그 앤 드롭으로 콘텐츠 복사를 구현하기 – Cocoa, Swift

(Cocoa | Swift) 문서기반 앱

NSDocument 코코아에서 도큐먼트 기반 앱은 Pages 등의 프로그램과 같이 단일 문서당 개별 윈도를 갖고 구동되는 앱이다. 이러한 앱은 다음의 특성을 가진다. 한 애플리케이션에서 문서의 개수만큼의 윈도를 열 수 있다. 앱은 여러 문서들을 관리하게 된다. 문서는 문서의 데이터 구조를 관리하며, 이러한 데이터를 표시하는 윈도우를 관리한다. 문서는 디스크에 문서의 데이터를 저장하고, 읽고, 새 문서를 시작하는 기능을 담당한다. 또한 iCloud에 문서를 저장하거나 옮기는 기능도 담당하게 된다. 도큐먼트 기반 앱은 단순한 유틸리티나 슈박스 앱과는 다른 구조를 가지고 있으며, 그만큼 복잡하고 많은 기능들을 제공해야 한다.… 더 보기 »(Cocoa | Swift) 문서기반 앱

iOS에서 사용할 수 있는 애니메이션 구현 기법들에 대한 정리

애니메이션 구현 방법

iOS의 애니메이션 구현은 크게 두 가지로 나눌 수 있는데 하나는 UIKit의 애니메이션 API를 사용하는 것이고, 다른 하나는 코어 애니메이션을 사용하는 것이다. 오늘은 각각의 세부적인 구현보다는 각각의 API의 차이와 기본적인 사용방법에 대해서 살펴보도록 하겠다.더 보기 »iOS에서 사용할 수 있는 애니메이션 구현 기법들에 대한 정리

복사-붙여넣기가 지원되는 클래스 작성하기 – Cocoa, Swift

복습

이전 시간에 macOS에서 클립보드를 통해서 복사와 붙여넣기를 통해서 뷰 혹은 앱간의 데이터를 교환하는 과정에 대해서 살짝 살펴보았다. 어떤 클래스의 객체가 클립보드로 복사되려면, 해당 클래스는 클립보드에게 어떤 타입의 데이터들을 넣어줄 수 있음을 알리고, 각 타입에 대한 데이터를 생성하여 클립보드에게 전달해주는 동작을 수행해야 하며, 이 동작은 NSPasteboardWriting에 정의되어 있다. 그리고 붙여넣는 시점에 특정한 클래스의 객체를 클립보드에 요청하면, 클립보드는 해당 클래스의 객체를 생성할 수 있는 타입들을 조사한 후, 조달 가능한 타입에 대응하는 데이터를 이용해서 해당 클래스 객체를 생성해 붙여넣는 쪽으로 전달해주게 된다. 즉 클립보드로부터 생성할 수 있는 클래스는, 객체를 생성할 수 있는 데이터의 타입과, 타입별 데이터를 전달받아 인스턴스를 만드는 방법을 알고 있어야 한다. 이 내용은 NSPasteboardReading에 정의된다.

복사/붙여넣기의 동작은 어떤 클래스로부터 이진데이터를 만들어서 클립보드에 올려놓고, 또 클립보드 데이터로부터 어떤 클래스를 만드는 일과 관련된다. 하지만 이것은 직렬화/역직렬화와는 다르다. 왜냐하면 복사/붙여넣기 동작은 앱과 앱 사이에서도 발생할 수 있는 일이기 때문이다. 따라서 데이터 공급과 소비의 관점에서 이해해야 하며, 이 때 오가는 데이터는 1가지 이상의 타입일 수 있다.

보통의 복사/붙여넣기 동작과 관련해서는 특수한 타입의 데이터보다는 일반적인 표준 클래스의 데이터를 더 많이 쓰게되므로 실질적으로 커스텀 클래스를 클립보드에 복사해넣는 일은 그리 많지 않다. 하지만 궁금해하지 말라는 법은 없으니, 복사/붙여넣기를 지원하는 커스텀 클래스를 어떻게 작성할 수 있는지에 대해서 알아보도록 하자. 

더 보기 »복사-붙여넣기가 지원되는 클래스 작성하기 – Cocoa, Swift

NSView의 내용을 PDF로 만들기 (Swift)

뷰로부터 pdf 데이터 얻기 AppKit의 모든 그리기 명령은 PDF로 변환가능하다. 그리고 이렇게 변환된 PDF 데이터는 프린터로 보내지거나 파일에 기록될 수 있다. PDF는 해상도에 의존하지 않기 때문에 어느 기기에서 봐도 제법 괜찮은 품질을 보여준다는 점을 잊지 말자. draw:를 사용해서 뷰를 그리는 것을 할 수 있다면, PDF는 공짜로 얻을 수 있다. 이 방법은 매우 쉬운데 NSView는 다음과 같은 메소드를 가지고 있다. func dataWithPDF(inside: NSRect) -> Data 이 메소드는 draw(:)를 호출해서 이를 통해 그래픽 데이터를 얻는다. 뷰 그리기 명령에서 얻어지는 모든 내역은 화면이… 더 보기 »NSView의 내용을 PDF로 만들기 (Swift)

(Swift | Tutorial) copy and paste 구현해보기

복사/붙여넣기를 지원하기

페이스트보드, 흔히들 클립보드라고 말하는 이 물건은 요즘 컴퓨터를 쓰는 사람들에게는 어찌보면 공기중의 산소와 같은 것이라 하겠다. 거의 모든 컴퓨터 및 스마트기기 사용자들이 의식하지도 않은채 많이 쓰는 기능일 것이다. 복사와 붙여넣기는 사용자 측면에서는 숨쉬는 것처럼 자연스러운 기능이지만,시스템 측면에서는 사실 간단한 동작은 아니다. 복사/붙여넣기는 단순히 앱 내에서 데이터를 이동하는 것 뿐만 아니라 서로 다른 앱 간에 대해서도 이를 통해서 데이터를 전달할 수 있게 된다.더 보기 »(Swift | Tutorial) copy and paste 구현해보기

Tap and Hold 구현하기 – iOS, Swift

tap and hold 구현하기

UIButton은 기본적으로 단일 탭에 대해서 액션 메시지를 발신하게끔 디자인되어 있고, 따라서 별도의 UITapGestureRecognizer가 없어도 동작할 수 있다. 하지만 더블탭, 트리플 탭이나 길게 누르기등의 동작에 대해서는 여타 다른 UIView들과 마찬가지로 동작 인식기를 필요로한다. 더 보기 »Tap and Hold 구현하기 – iOS, Swift

대용량 텍스트 파일을 한줄씩 읽기 – StreamReader를 작성하자

특정한 텍스트 파일을 읽어들여서 한 줄씩 처리하는 방법에서 가장 간단한 구현은 Stringinit(contentOfURL:encoding:)을 이용하여 텍스트 파일의 내용 전체를 하나의 문자열로 만든 다음에, 개행 문자를 이용해서 자르는 것이다.

let path = "~/Downloads/sample.txt"
let url = URL(fileURLWithPath: (NSString(string:path).expandingTildeInPath) // #1, #2
if let s = String(contentsOf: url) {
    for line in s.components(separatedBy:.newlines) {
        print(line)
    }
}

더 보기 »대용량 텍스트 파일을 한줄씩 읽기 – StreamReader를 작성하자

커스텀 뷰로 만든 UI 컴포넌트의 포커스링 그리기 – Cocoa

포커스 링

코코아 UI 요소에서 현재 포커스를 받은 UI 컴포넌트는 외부에 흐릿한 푸른 색 후광이 그려지며, 현재 포커스를 받고 있는 입력 디바이스라는 점을 시각적으로 피드백한다.  시중의 코코아 관련한 대부분의 책에서는 다음과 같이 draw: 메소드 내에서 포커스링을 그리는 것으로 포커스링을 흉내낼 수 있다고 한다. 1

override func draw(_ dirtyRect: NSRect) {
    // 배경을 칠하고,
    super.draw(dirtyRect)
    self.bgColor.set()
    NSBezierPath.fill(bounds)
    // 자신이 속한 윈도에서 자기가 제1응답자라면?
    if let fr = window?.firstResponder, fr === self {
        // 포커스 컬러로 세팅하여, 자신의 테두리 영역을 그린다.
        NSColor.keyboardFocusIndicatorColor.set()
        NSBezierPath.setDefaultLineWidth(4.0)
        NSBezierPath.strokeRect(bounds)
    }
}

그리고 제 1 응답자가 되었을 때 포커스링을 그리기 위해서는 뷰가 응답자 상태에 진입하거나 빠져나올 때마다 뷰를 새로 그리도록 갱신해야 한다.

override var acceptsFirstResponder: Bool { return true }
override func resignFirstResponder() -> Bool {
    NSLog("Resigning...")
    setNeedsDisplay(bounds)
    return true
}
override func becomeFirstResponder() -> Bool {
    NSLog("Becoming...")
    setNeedsDisplay(bounds)
    return true
}

더 보기 »커스텀 뷰로 만든 UI 컴포넌트의 포커스링 그리기 – Cocoa

(Swift) UIDynamic 예제

이전에 작성했던 UIDynamics 데모를 재작성했다.

  • swift3 문법을 적용했고,
  • 별도의 Xcode 프로젝트가 아니라 Playground 용으로 만들어서 바로 확인할 수 있게 했다.

UIDynamics를 적용하는 방법은 UIDynamicAnimator 객체를 만들고 여기에 애니메이션에 고려될 물리학적 요소 (중력이나 마찰등)를 behaivor로 설정해주면 된다. 애니메이터는 기준이 되는 레퍼런싱 뷰를 참조하면서 생성되고, 이후 해당 뷰 내의 뷰 계층 구조에 대해서 동역학을 계산하게 된다.
더 보기 »(Swift) UIDynamic 예제