NSTouchBar

Panther·2021년 8월 8일
0

https://developer.apple.com/documentation/appkit/nstouchbar

"An object that provides dynamic contextual controls in the Touch Bar of supported models of MacBook Pro."

맥북 프로 중 지원되는 모델의 터치바에서 동적 contextual 컨트롤을 제공하는 객체입니다.

Declaration

@MainActor class NSTouchBar : NSObject

Overview

지원되는 맥북 프로 모델에서 키보드 위에 있는 터치 바는 프론트 모스트 앱으로부터 NSTouchBar 클래스의 인스턴스를 보여줍니다. 이와 같은 인스턴스는 간단히 바라고 부릅니다. 사용자의 컨텍스트에 관련이 있는 컨트롤을 제공하기 위해 바를 정의할 수 있습니다. 각각의 이러한 컨트롤은 NSTouchBarItem 클래스의 인스턴스이며, 간단히 아이템이라고 부릅니다.

Figure 1 Bars and items from the TextEdit app

앱에서 여러 바를 제공할 수 있으며, 각각은 리스폰더 인스턴스당 하나입니다. macOS 프레임워크는 앱의 바 얖에 나타날 수 있는 바를 제공할 수 있습니다. 시스템은 한 시점에 보여줄 바를 결정합니다. 예를 들어 텍스트 필드(NSTextField 클래스의 인스턴스)와 같은 AppKit 객체는 관련 아이템과 함께 적합한 바를 얻습니다.

NSScrubber 클래스를 포함해 NSTouchBar 및 관련 클래스 사용 방법을 설명하고 있는 아래 샘플 코드 프로젝트를 참조하시기 바랍니다. 풍부한 API를 포함하고 있으며, 이 API들은 커스터마이징된 picker 컨트롤을 빌드할 수 있도록 해줍니다.

  • Creating and Customizing the Touch Bar — 터치 바에서 사용하기 위한 바 및 아이템 생성 방법을 보여줍니다.

  • Integrating a Toolbar and Touch Bar into Your App — 맥 앱에 터치 바 지원을 추가하는 방법을 보여줍니다.

Creating and Customizing the Touch Bar
https://developer.apple.com/documentation/appkit/touch_bar/creating_and_customizing_the_touch_bar

Integrating a Toolbar and Touch Bar into Your App
https://developer.apple.com/documentation/appkit/touch_bar/integrating_a_toolbar_and_touch_bar_into_your_app

터치 바를 사용하려면 NSTouchBar 객체에서 설명하고 있는 앱의 리스폰더 체인에서 객체에 바를 정의해야 합니다. 런타임에 시스템은 앱 및 연결한 프레임워크로부터 바를 찾고, 조합하고, 보여주기 위해 리스폰더 체인을 탐색합니다.

리스폰더 체인에서 더 낮은 막대의 항목을 포함하는 확장된 형태로 바를 보여주는(즉 첫 번째 리스폰더에 가까운) 동적 컴포지션을 지원하기 위해 바를 설정할 수도 있습니다. 동적 컴포지션 및 터치바에 보이는 아이템의 위치 때문에, 지원하는 macOS 버전에서 테스트하면서 바가 기대한 모습으로 나타나는지 확실히 해야 합니다.

NSTouchBar 클래스의 인스턴스는 제스쳐 리코그나이저를 사용하고 macOS 10.12.1 이벤트 개선사항의 이점을 활용합니다. 터치 바의 물리적 모양 때문에 제스쳐 리코그나이저에 전달되는 터치 이벤트는 오직 x 혹은 수평 컴포넌트만 의미가 있습니다.

사용 가능한 터치 바가 있는지 여부에 대해 앱이 알 수 있도록 API가 필요하지 않으며, 그러한 API가 존재하지도 않습니다. 앱이 터치 바를 지원하는 기기에서 실행되고 있는지와 관계없이 앱은 앱의 화면에서 UI가 같은 방법으로 나타나고 동작합니다.

터치 바는 맥북 프로의 스크린처럼 레티나 디스플레이입니다. 터치 바 내부에서 커스텀 드로잉 혹은 애니메이션을 수행하려면, 스크린에서 하는 것과 동일한 모범 사례를 따르시기 바랍니다. Performance Considerations for the Touch Bar를 읽어야 합니다.

Performance Considerations for the Touch Bar는 이 글의 아래 부분에 나옵니다.

Note
터치 바가 디스플레이일지라도 이것은 첫 번째이자 가장 앞에 있는 입력 장치입니다. 터치 바 사용에 있어 디스플레이만을 갖는 요소를 제공하기 위해 사용하지 않으시기 바랍니다.

터치 바의 오른쪽에서 시스템은 항상 사용이 가능한 컨트롤 스트립을 제공합니다. 컨트롤 스트립은 사용자에게 화면 밝기, 사운드 볼륨, 시리 등에 대한 표준 컨트롤을 위한 접근성을 제공합니다. 앱의 바는 컨트롤 스트립의 왼쪽에 나타납니다. 사용자는 가장 앞에 있는 앱 전체를 터치 바 넓이에 줄 수 있도록 컨트롤 스트립을 숨길 수 있습니다. NSTouchBar Layout에서 바가 사용 가능한 넓이에 반응하는 방법에 대해 읽어보시기 바랍니다.

NSTouchBar Layout은 이 글의 뒷부분에 나옵니다.

컨트롤 스트립의 오른쪽은 터치 ID 센서입니다. 터치 ID를 사용하려면 Local Authentication 프레임워크로부터 메소드를 사용하시기 바랍니다.

Local Authentication
https://developer.apple.com/documentation/localauthentication
https://velog.io/@panther222128/Local-Authentication-fqhjd29z

터치 바는 자동으로 어두워지고 사용자가 터치하면 깨어납니다. 터치 바에서 경고를 표시하지 않아야 하며, 위젯으로 사용하지도 않아야 합니다.

터치 바 디자인 가이드는 macOS Human Interface Guidelines에 있는 About the Touch Bar를 읽어보시기 바랍니다.

macOS Human Interface Guidelines
https://developer.apple.com/design/human-interface-guidelines/macos/overview/themes/#//apple_ref/doc/uid/20000957

NSTouchBar Objects

NSTouchBarItem 객체(혹은 아이템)의 배열을 갖는 NSTouchBar 객체(혹은 바)와 툴바 아이템을 갖는 윈도우 혹은 메뉴 아이템을 갖는 메뉴가 유사하다고 생각할 수 있습니다.

앱에서 바를 제공하려면 세 가지 요구사항을 충족하는 객체에 정의하시기 바랍니다. 바를 정의하는 객체는 아래와 같아야 합니다.

  • 런타임에 리스폰더 체인 내부에서 나타나는 리스폰더(NSResponder 서브클래스의 인스턴스)여야 합니다.
  • NSTouchBarProvider 프로토콜로부터 makeTouchBar() 메소들르 구현해야 합니다.

내장된 리스폰더 클래스는 NSTouchBarProvider를 따르고 있고 키-값 옵저빙(KVO)를 지원하며, 이들은 모두 NSTouchBar 인프라에 의해 사용되고 요구됩니다. 터치 바 지원의 컨텍스트에서 리스폰더 인스턴스는 바 제공자라고 부르기도 합니다.

Listing 1은 makeTouchBar() 딜리게이트 메소드의 구현 예시를 보여줍니다. 코드 스니펫에서 커스터마이징과 관련이 있는 문장을 볼 수 있습니다. 바는 NSTouchBar Customization에서 설명하는 사용자 커스터마이징을 지원합니다.

NSTouchBar Customization은 이 글의 뒷부분에 나옵니다.

Listing 1 Using the makeTouchBar method

override func makeTouchBar() -> NSTouchBar? {
    let mainBar = NSTouchBar()
    mainBar.delegate = self    mainBar.customizationIdentifier = .imageViewer
    mainBar.defaultItemIdentifiers = [.sharingPicker, .strokePopover, .strokeColorPicker, .photoPicker, .flexibleSpace, .clearButton, .otherItemsProxy]
    mainBar.customizationAllowedItemIdentifiers = [.strokeSlider, .strokePopover, .photoPicker, .strokeColorPicker, .clearButton, .sharingPicker, .flexibleSpace]
    mainBar.principalItemIdentifier = .photoPicker
    return mainBar
}

사용자가 커스터마이징하고 터치 바와 상호작용할 때, 어떤 아이템이 시각화되어 있는지와 같은 바의 상태 추적이 가능하며, 이 추적을 유지하기 위해 내장된 KVO 지원을 활용할 수 있습니다.

만약 앱 딜리게이트 내부 혹은 윈도우 딜리게이트 내부에서 명시적으로 NSTouchBarProvider를 채택하고 있다면, NSTouchBar 메소드 구현의 내부에서부터 관련 KVO 노티피케이션을 명시적으로 보내야 합니다. 이는 시스템이 바에서의 변경에 대해 적절하게 응답할 수 있도록 해줍니다. KVO 지원으로 수동으로 할 필요가 없도록 앱 딜리게이트 대신 바 제공자로써 앱 객체를 사용하거나, 관련 윈도우 딜리게이트 대신 윈도우 컨트롤러 혹은 윈도우를 바 제공자로써 사용하시기 바랍니다.

바의 상태를 변경시키고자 하는 이유가 있는 상황처럼 바와 관련이 있는 바 제공자를 무효화하려면, 바 제공자의 touchBar 속성을 nil 값으로 설정하시기 바랍니다.

Using NSTouchBarItem Objects

바 자체(NSTouchBar 객체)로써는 맥북 프로 터치 바에서 시각적 표현을 갖지 않습니다. 대신 사용자는 NSTouchBarItem 클래스의 인스턴스로 표현되는 바의 아이템을 볼 수 있습니다.

Note
이 섹션은 바에서 아이템을 사용하기 위한 방법을 설명하고 있습니다. 다양한 종류의 아이템 및 이러한 아이템의 생성과 설정 방법은 NSTouchBarItem 클래스 레퍼런스를 보시기 바랍니다.

NSTouchBarItem
https://developer.apple.com/documentation/appkit/nstouchbaritem

바에서 나타나는 아이템들은 바가 소유하고 있는 private 배열에서 원소들입니다. 바에서 아이템을 구체화하려면 이 배열을 직접 채우기보다 아이템의 다양한 그룹 및 직접 구체화한 아이템 아이덴티파이어에 기반하는 아이템들을 관리하는 바에 의존해야 합니다.

바를 위해 아이템을 구체화하는 것은 두 가지 옵션을 갖고 있으며, 이로써 리소스 사용 최적화에 유연함을 확보하고, 앱에서 효율성을 가질 수 있습니다.

  • templateItems 속성은 바를 위한 아이템 인스턴스로 직접 채울 수 있는 집합입니다. 앱의 생명주기에서 메모리에 머무르기 충분할 정도로 가벼운 아이템들이고, 아이템이 시간에 걸쳐 변하는 상태를 포함하지 않는 경우 이 옵션을 사용하시기 바랍니다.
  • NSTouchBarDelegate 프로토콜과 이 프로토콜의 touchBar(_:makeItemForIdentifier:) 딜리게이트 메소드는 필요한 때에 아이템을 생성하는 방법을 제공합니다. 리소스 사용 및 동적 상태 반영의 관점에서 합리적인 경우 이 옵션을 사용하시기 바랍니다.

두 가지 접근법 중 어떤 것을 사용하더라도 시스템은 세 가지에 기반해 바의 private 아이템 배열을 채울 책임이 있습니다.

  1. NSTouchBar Customization에서 설명하는 것처럼 바의 아이템 아이덴티파이어 속성 설정에 기반합니다.
  2. NSTouchBar Composition and Nesting에서 설명하는 것처럼 구체화한 모든 중첩에 기반합니다.
  3. 사용자가 바에서 구체화한 모든 커스터마이징에 기반합니다.

앱이 실행될 때, 읽기 전용 itemIdentifiers 속성에 접근함으로써 바에서 나타날 수 있는 아이템의 아이덴티파이어(구체적으로 private 아이템 배열에 있는 것들)를 가져올 수 있습니다. 이 속성은 사용자에 의해 수행되었던 모든 커스터마이징 및 시스템에 의해 수행되었던 모든 동적 컴포지션을 포함해 바 인스턴스의 현재 상태를 반영합니다.

NSTouchBar Customization

AppKit은 메인 디스플레이에서 사용자 요청에 따라 나타나는 풍부한 터치 바 커스터마이징 기능을 제공합니다. 특정 UI가 필요하지 않는 한 바를 커스터마이징 가능한 상태로 만드시기 바랍니다. 커스터마이징 가능한 바는 자동으로 사용자가 아래처럼 할 수 있는 UI를 갖습니다.

  • 보이는 바의 부분으로 어떤 아이템을 변경할 수 있도록 합니다.
  • 보이는 바에서 아이템을 재정렬합니다.

사용자는 The Customization Menu Item에서 설명하는 것처럼 전용 메뉴 아이템을 선택함으로써 화면 커스터마이징 UI를 호출합니다.

NSTouchBar 객체를 커스터마이징 가능하도록 하려면, 이를 globally-unique customizationIdentifier 아이덴티파이어 할당을 하시기 바랍니다. 아이덴티파이어 스트링에서 “com.company-name.app-name.alphanumeric-ID”처럼 reverse-DNS 스타일을 사용하시기 바랍니다.

다음으로 아이템 아이덴티파이어 리스트를 채움으로써 바의 아이템 및 커스터마이징 가능성을 구체화해야 합니다. 이러한 각각의 리스트는 배열입니다. 각각의 요소가 아이템(NSTouchBarItem 객체)에 대한 아이덴티파이어(NSTouchBarItem.Identifier 타입의)입니다. 바의 아이템 아이덴티파이어 리스트는 아래 내용에 해당합니다.

Default item identifiers입니다. 바의 defaultItemIdentifiers 속성에서 구체화됩니다. NSTouchBar 객체에 대해 항상 이 속성을 구체화해야 합니다. 바를 커스터마이징 불가능하게 하더라도 그렇게 해야 합니다. 시스템은 아래 내용을 수행합니다.

  • 시스템이 바를 표시할 때, 기본값으로 리스트의 아이템들을 보여줍니다.
  • 관련 커스터마이징 UI에서 아이템들을 포함해 사전에 설정된 바 표현을 포함합니다. (customizationIdentifier 속성 값을 할당함으로써 커스터마이징 가능한 바로 선언했을 경우) 사용자는 기본값 설정으로 돌아가고 싶은 경우 터치 바에 기본값 바를 드래그할 수 있고,

Additional item identifiers입니다. 바의 customizationAllowedItemIdentifiers 속성에서 구체화됩니다. 커스터마이징 가능한 바에 대해서 항상 이 속성을 설정해야 합니다. 시스템은 속성 배열에서 구체화한 것과 같은 순서로 정렬된 커스터마이징 UI에서 아이템을 개별적으로 나타내는 것을 보어줌으로써 이 리스트를 사용합니다. 사용 가능한 기하학적 공간이 있는 경우 사용자는 이 리스트에 있는 아이템을 활성화된 바에 드래그할 수 있습니다. 만약 충분한 공간이 없다면 드래그된 아이템은 아이템을 교체하거나 새 아이템이 드롭되는 지점 아래에 있는 아이템을 교체합니다.

Required item identifiers입니다. 바의 customizationRequiredItemIdentifiers 속성에서 구체화됩니다. 앱의 디자인에 따라 의도에 맞게 이 속성을 설정하시기 바랍니다. 사용자는 이 리스트에 구체화한 아이템을 바에서 제거할 수 없습니다.

커스터마이징 UI에서 텍스트의 레이블을 제공하려면, 커스터미이징 가능한 바에 포함시킨 각각의 NSTouchBarItem 인스턴스에 대해 customizationLabel 속성을 사용하시기 바랍니다. macOS에 있는 접근성 시스템 또한 이 레이블들의 사용을 만듭니다.

만약 앱 디자인이 커스터마이징 불가능한 NSTouchBar 객체를 요구하는 경우 아래처럼 하시기 바랍니다.

  • defaultItemIdentifiers 속성에 바의 아이템 모두에 대한 리스트를 만들고, 이 속성에만 넣습니다.
  • 이 섹션에서 설명한 다른 속성을 사용하지 않아야 하며, 특히 바에 customizationIdentifier 속성 값을 할당하지 않아야 합니다.

Group Item, Popover Item, and Composed Bar Customization

AppKit은 커스터마이징 가능하거나 그렇지 않은 경우 모두를 포함한 바를 구체화할 수 있도록 해줍니다. 바에 대해 제공하는 커스터마이징 설정은 바에 연관된 형태로 남습니다(이러한 아이템들이 리스폰더 체인에서 더 높은 곳에 있는 다른 바 속에 시스템에 의해 중첩된 때에도 그렇습니다). 리스폰더 체인에서 바 컴포지션에 대한 자세한 내용은 NSTouchBar Composition and Nesting을 살펴보시기 바랍니다.

NSTouchBar Composition and Nesting은 이 글의 아래 부분에 나옵니다.

시스템은 그룹과 팝오버 아이템을 사용할 때에도 바 커스터마이징 설정을 존중합니다. 이러한 아이템 타입 각각은 그 자체로 하나 혹은 이상의 바를 갖습니다(그룹 아이템과 팝오버 아이템을 차례대로 포함할 수 있습니다). 이 섹션의 나머지 부분은 그룹 아이템과 팝오버 아이템을 포함하는(그리고 바 내부에도)바에 대한 커스터마이징이 어떻게 작동하는지를 설명합니다.

A group item (NSGroupTouchBarItem 클래스의 인스턴스)는 객체의 groupTouchBar 속성에서 쥐고 있는 채로 하나의 바를 갖습니다. AppKit은 하나 혹은 하나 이상의 그룹 아이템을 포함하도록 groupTouchBar 바를 그 자체로 설정할 수 있다는 점에서 그룹 아이템의 중첩을 지원합니다(혹은 앱에서 어떤 것이 잘 작동하는지 가이드된 모든 다른 타입의 아이템들). 그룹 아이템에 대한 커스터마이징이 실제로 어떻게 작동하는지의 예시가 여기에 있습니다.

  • 만약 바를 커스터마이징 가능하게 설정하고 여기에 커스터마이징이 불가능한 것으로써 설정한 바를 갖는 그룹 아이템을 넘기면, groupTouchBar 바에 있는 아이템의 배열이 atomic 유닛으로써 커스터마이징 UI에 나타납니다. 커스터마이징 동안, 사용자는 아이템의 배열을 조작할 수 있지만, 엄격하게 유닛으로써 조작할 수 있습니다. 만약 (커스터마이징 불가능한) 터치 바에서 groupTouchBar 바가 시각화되면, 사용자는 유닛으로써 이를 제거할 수 있고 혹은 groupTouchBar 바에서 재정렬할 수 있습니다. 만약 groupTouchBar 바가 커스터마이징 UI에서 대신 시각화되는 경우 사용자는 유닛으로써 터치 바에 되돌려 추가할 수 있습니다. 그룹 아이템을 갖는 바 내부에 위치시키게 됩니다.
  • 만약 바를 커스터마이징 불가능하게 설정하고, 커스터마이징 가능한 것으로 설정한 바를 갖는 그룹 아이템을 주는 경우 groupTouchBar의 아이템은 개별 아이템으로써 머스터마이징 UI에 나타납니다. 커스터마이징 동안 사용자는 각 아이템을 분리해서 조작할 수 있습니다. 만약 groupTouchBar 바로부터의 아이템이 터치 바에서 시각화되면, 사용자는 이를 제거하거나 groupTouchBar 아이템 중에서 재정렬할 수 있습니다. 만약 groupTouchBar 바로부터의 아이템이 커스터마이징 UI에서 대신 시각화되면, 사용자는 터치 바에 되돌려 추가할 수 있습니다. 개별적으로 아이템을 갖고 있는 groupTouchBar 바 내부 어느 곳에 위치시킵니다.

A popover item (NSPopoverTouchBarItem 클래스의 인스턴스)은 두 개의 바를 갖습니다. 하나는 popoverTouchBar에서 구체화한 바이고, 두 번째는 pressAndHoldTouchBar 속성에서 구체화할 수 있는 선택적 바입니다. 팝오버 아이템에 대한 커스터마이징이 실제로어떻게 작동하는지에 대한 예시가 여기에 있습니다.

  • 만약 바를 커스터마이징 가능한 것으로 설정하고 커스터마이징 불가능하게 설정한 popoverTouchBar 바를 갖는 팝오버 아이템을 주면, popoverTouchBar 바는 커스터마이징 UI에 나타나지 않습니다. 만약 사용자가 팝오버 아이템(커스터마이징 불가능한)이 그 자체(버튼의 popoverTouchBar 바에 관련이 있는 것이 아닌)로 터치 바에서 시각적인 경우 커스터마이징 UI를 호출하면, 커스터마이징 UI는 사용자가 팝오버 아이템을 다른 아이템에 상대적인 위치로 재정렬할 수 있돌고 해줍니다. 반면에 사용자가 (커스터마이징 불가능한) popoverTouchBar 바가 터치 바에서 시각화되는 경우 커스터마이징 UI를 호출하면, 시스템은 팝오버를 해제하고 커스터마이징 UI에서 팝오버 아이템을 포함하는 바에 대한 커스터마이징 옵션을 보여줍니다.

  • popoverTouchBar 바를 커스터마이징 가능한 형태로 설정하는 경우 사용자는 popoverTouchBar를 호출할 수 있고, 그러면 popoverTouchBar 바 자체에 있는 아이템을 조작하기 위해 커스터마이징 UI를 사용할 수 있습니다.

The Customization Menu Item

사용자는 특정 NSTouchBar 객체가 시각화될 때, 바 커스터마이징 메뉴 아이템을 선택함으로써 특정 해당 객체에 대한 커스터마이징 UI를 호출합니다. 이 메뉴 아이템을 활성화하려면 명시적으로 opt-in 해야 합니다. 아래 방법으로 수행할 수 있습니다.

  • 앱의 메뉴에서 메뉴 아이템을 명명, 위치시키기, 유효성 검사, 활성화를 자동으로 하기 위해 시스템을 원한다면, 앱 객체의 isAutomaticCustomizeTouchBarMenuItemEnabled 속성을 true로 설정하시기 바랍니다.
  • 앱 메뉴의 한 곳에 커스터마이징 메뉴 아이템을 명시적으로 위치시키려면, 앱 객체의 toggleTouchBarCustomizationPalette(_:) 메소드를 사용해야 합니다. 이렇게 하는 경우 시스템은 메뉴 아이템의 이름을 짓고 유효성 검사를 하며, 터치 바를 갖지 않는 시스템에서 숨깁니다.

만약 커스터마이징 메뉴 아이템 사용을 시도하고 있지만(두 접근방식 어떤 것을 사용하더라도) 바에 대한 커스터마이징 아이덴티파이어 속성(customizationIdentifier)을 제공하지 않고 있다면, 커스터마이징 메뉴 아이템은 바가 활성화일 때 나타납니다(이 경우 메뉴 아이템은 사용이 불가능합니다).

만약 자동 및 커스터마이징 메뉴 아이템의 명시적 위치시키기 모두를 사용하길 시도한다면, 시스템은 명시적인 컨트롤을 우선으로 보고, 아이템을 자동으로 위치시키지 않습니다.

NSTouchBar Layout

사용자는 컨트롤 스트립의 넓이를 제어하고 숨기기를 선택할 수 있습니다. 그리고 시스템은 NSTouchBar 인스턴스(컴포지션 가능하도록 만든 바에 대한)를 중첩시키는 책임이 있습니다. 결과적으로 바에서 사용 가능한 디스플레이 넓이는 다양할 수 있습니다. 현재 사용 가능한 디스플레이 넓이를 가져올 수 있는 API는 존재하지 않습니다.

레이아웃 디자인에서 특정 컨트롤 스트립 사이즈에 의존하지 않도록 해야 합니다. 동적 컴포지션과 바에 대한 중첩을 기대해야 합니다.

사용 가능한 것보다 더 큰 수평 공간이 필요한 경우 팝오버 아이템, 스크러버, 혹은 스크롤 뷰를 사용하시기 바랍니다(디자인 요구사항에 맞도록 내림차순, preference 순으로).

geometric-space-constrained 시나리오에서 시스템은 시각적 우선순위에 따라 NSTouchBarItem 인스턴스를 숨깁니다. NSTouchBarItem Configuration에 있는 "NSTouchBarItem priority for visibility”를 읽어보시기 바랍니다.

NSTouchBarItem Configuration
https://developer.apple.com/documentation/appkit/nstouchbaritem#2587673

터치 바에서 아이템을 중앙에 위치시킬 필요가 있는 경우 아이템을 바의 principalItemIdentifier 속성에 할당함으로써 principal 아이템으로 선언해야 합니다. 아이템이 중앙에 놓여질 수 있도록 하드 코딩하지 않아야 합니다. 터치 바에서 그룹 아이템이 중앙에 놓여지길 원한다면, 그룹 아이템(NSGroupTouchBarItem타입의)을 principal 아이템으로 선언해야 합니다.

NSTouchBar Composition and Nesting

리스폰더 체인의 아래에 있는 바로부터 아이템을 포함하는 확장된 형태에서 시스템으 바를 보여줄 수 있는 동적 컴포지션을 지원하도록 바를 설정할 수 있습니다(즉 첫 번째 리스폰더에 가까운).

바가 중첩에 대한 컨테이너로써 제공하도록 하려면, 바의 defaultItemIdentifiers 배열에 otherItemsProxy 아이템 아이덴티파이어를 추가해야 합니다. 리스폰더 체인에서 상대적으로 높이 있으면서 이 아이덴티파이어를 갖는 바는, 리스폰더 체인에 상대적으로 낮은 곳에 있는 사용 가능한 바로부터 아이템을 포함할 수 있습니다(런타임에).

바의 defaultItemIdentifiers 배열 내부에서 다른 아이템 프록시에 대해 구체화한 위치는 시스템에게 중첩된 아이템이 어느 곳에 놓여지길 원하는지를 알려줍니다.

시스템은 시스템 정책 및 터치 바에서 사용 가능한 공간에 기반해, 이러한 방법으로 구성한 바인지 아닌지 결정합니다.

NSTouchBar 객체 중첩은 터치 바에서 사용 가능한 공간에 따라 연결지어질 수 있습니다. 예를 들어 뷰 내부에 있는 뷰 및 텍스트 필드는 부모 윈도우 컨트롤러에서 정의된 바에 아이템을 구성하도록 할 수 있습니다.

시스템이 하나의 바 아이템을 리스폰더 체인에 더 높이 있는 다른 바에 중첩실 때, 아이템은 터치 바에서 더 높은 바에 통합된 형태로 사용자에게 나타납니다. 중첩된 것으로써 아이템이 구분될 수 있도록 하는 시각적 경계선이나 추가적인 공간은 없습니다.

바가 otherItemsProxy 아이덴티파이어를 사용하지 않는 경우 시스템은 리스폰더 체인 아래에 있는 다른 바가 표시 가능한 상태일 때 해당 바를 숨깁니다.

현재 첫 번째 리스폰더에 대해 터치 바에서 보여줄 아이템을 결정하는 경우 시스템은 전체 리스폰더 체인을 탐색합니다. 이는 시스템이 체인에서 더 높이 있는 객체에 대해 정의된 바에 있는 모든 프록시 아이템을 수용할 수 있게 해주고, 그럼으로써 리스폰더 체인에서 위치에 있는 객체에 대해 정의된 모든 바가 other-items-proxy 아이덴티파이어를 포함할 수 있도록 해줍니다.

Customization for Composed Bars

중첩된 NSTouchBar 객체에 대한 논리적, 기하학적 경계는 터치 바에서 사용자에게 보이지 않습니다. 그러나 경계는 커스터마이징 관점에서 효과로써 남아있습니다. 사용자는 경계 밖에서 중첩된 바의 아이템을 재정렬할 수 있습니다.

예를 들어 (여기서는 ASCII-art를 사용해서) 바가 있다고 가정하고, 리스폰더 체인에서 높은 곳에 아래처럼 설정된 경우를 생각할 수 있습니다.

[(1)(2)(other-items-proxy)(3)]

그리고 시스템 및 현재 앱 상태에 따라 터치 바에서 표시 가능한, 리스폰더 체인 아래에 있는 바 역시 갖고 있다고 가정하겠습니다.

[(A)(B)(C)]

구성된 바는 터치 바에서 이 정렬에 상응하게 될 것입니다.

[(1)(2)(A)(B)(C)(3)]

커스터마이징 UI를 사용하면 사용자는 (A), (B), (C) 순으로 나타나 있는 아이템으로 재정렬할 수 있습니다. 이는 재정령 동안 연속적 형태로 남아있는 아이템에 한해서 그렇습니다. 이렇게 함으로써 아이템을 정의하는 바의 논리적 경계는 유지됩니다.

Item Spacing for Composed Bars

시스템이 공간 아이템을 포함하는 NSTouchBar 객체를 중첩시키는 경우 인접 간격을 병합합니다. 원하는 모양으로 나타날 수 있도록 확실히 해줘야 하며, 지원하는 macOS 버전에 대해 테스트해야 합니다. 공간 아이템에 대한 더 많은 정보는 Other Common NSTouchBarItem Types를 살펴보시기 바랍니다.

Other Common NSTouchBarItem Types
https://developer.apple.com/documentation/appkit/nstouchbaritem#2870924

NSTouchBar Discovery and the Responder Chain

런타임에 시스템은 NSTouchBarProvider 프로토콜을 따르는 객체를 찾기 위해 초점을 갖는 객체에서 시작해서 리스폰더 체인을 탐색합니다. 이와 같은 객체는 바 제공자라고 부릅니다. 그러면 시스템은 터치 바를 잠재적으로 여럿인, 중첩된 바로 터치 바를 채웁니다. 이는 시스템 정책 및 사용 가능한 공간에 따라 채워집니다.

구체적으로 시스템에 의한 탐색은 하단으로부터 상단으로 진행되며, 아래 리스트와 같습니다.

  1. 앱 딜리게이트입니다.
  2. 앱 객체입니다.
  3. 메인 윈도우의 컨트롤러입니다.
  4. 메인 윈도우의 딜리게이트 입니다.
  5. 메인 윈도우입니다.
  6. 메인 윈도우의 첫 번재 리스폰더입니다.
  7. 키 윈도우의 컨트롤러입니다.
  8. 키 윈도우의 딜리게이트입니다.
  9. 키 윈도우입니다.
  10. 키 윈도우의 첫 번째 리스폰더 입니다.

시스템이 NSResponder 서브클래스의 인스턴스인 바 제공자를 만나면, 시스템은 해당 객체에 고정된 리스폰더 체인을 추가적으로 검색합니다.

예를 들어 복잡하지만 표준 앱에서 바 검색은 아래와 같을 것입니다. 하단에서 상단으로 탐색합니다.

  1. 앱 딜리게이트입니다.
  2. 앱 객체입니다.
  3. 키 윈도우의 컨트롤러입니다.
  4. 키 윈도우입니다.
  5. 윈도우의 루트에 가장 가까운 뷰 컨트롤러입니다.
  6. 윈도우의 루트에 가장 가까운 뷰입니다.
  7. 뷰 컨트롤러와 뷰 중간입니다.
  8. 키 윈도우 첫 번째 리스폰더의 뷰 컨트롤러입니다.
  9. 키 윈도우의 첫 번째 리스폰더입니다.

터치 바는 다른 것에 중첩된 하나의 바를 보여줄 수 있습니다. NSTouchBar Composition and Nesting에서 설명한 것과 같습니다.

NSTouchBar Composition and Nesting은 이 글의 윗부분에 나옵니다.

Accessibility and the Touch Bar

AppKit 뷰 및 컨트롤은 NSAccessibilityProtocol 프로토콜을 채택하고 자동으로 적합한 접근성 노티피케이션을 보냅니다. 터치 바는 AppKit과 함께 작동되도록 디자인되었기 때문에 터치 바는 접근 가능성을 갖습니다.

커스터마이징 가능한 것으로써 선언하는 모든 NSTouchBarItem 인스턴스에 customizationLabel 속성 사용을 확실히 해야 합니다(NSTouchBar Customization에서 설명한 것과 같습니다. macOS에 있는 접근성 시스템은 이 레이블의 사용을 만듭니다.

NSTouchBar Customization은 이 글의 윗부분에 나옵니다.

접근성에 대해 더 알고 싶으시다면 Accessibility Programming Guide for OS X을 살펴보시기 바랍니다.

Accessibility Programming Guide for OS X
https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/index.html#//apple_ref/doc/uid/TP40001078

AppKit Support for the Touch Bar

터치 바 기능을 지원하기 위해 AppKit은 macOs 10.12.1에서 처음으로 사용이 가능한 몇 가지 개선사항을 제공합니다.

  • Scrubbers. 관련 API와 함께 NSScrubber 클래스는 유연하고 수평 기반의 picker를 커스텀 아이템(NSCustomTouchBarItem 클래스의 인스턴스)에 추가하는 방법을 제공합니다.

  • Gesture recognizer support.

    • 바 아이템에서 NSMagnificationGestureRecognizer 클래스를 사용할 수 있습니다. 두 손가락 핀치 제스쳐를 활성화하려면, 제스쳐 리코그나이저에서 리코그나이저의 allowedTouchTypes 마스크 속성을 NSTouch.TouchType.direct 상수로 설정해야 하며, 이 상수는 NSTouch.TouchType.direct 열거형에 나와있습니다.
    • NSGestureRecognizer 추상 클래스는 터치 이벤트에 대한 응답을 구현할 수 있도록 해주는 메소드의 집합과 함께 개선되었습니다. touchesBegan(with:), touchesCancelled(with:), touchesEnded(with:), touchesMoved(with:) 메소드입니다.
    • NSClickGestureRecognizer, NSPanGestureRecognizer, NSPressGestureRecognizer 구체화 클래스는 각각 numberOfTouchesRequired 속성과 함께 개선되어 제스쳐 일치를 위해 요구되는 터치의 수를 구체화할 수 있도록 해줍니다.
  • Touch type changes. 커스텀 뷰에서 터치 이벤트를 활성화하려면, 뷰의 allowedTouchTypes 속성에 direct 값을 설정해야 합니다. (macOS 10.12.1에서 acceptsTouchEvents 속성은 새로운 allowedTouchTypes 속성에 따라 deprecate되었습니다.

  • Touch changes. NSTouch 클래스는 터치 바를 지원하기 위한 새로운 속성과 두 가지 세로운 메소드를 갖습니다. NSTouch.TouchType, location(in:), previousLocation(in:)입니다.

  • Control appearance support. NSButton, NSSegmentedControl, NSSlider 클래스는 각각 모양 지원 속성과 함께 개선됩니다. 버튼에 대한 bezelColor, 세그멘티드 컨트롤에 대한 selectedSegmentBezelColor, 슬라이더에 대한 trackFillColor입니다. (터치 바를 사용하면 슬라이더 아이템이 사용됨에 따라 슬라이더를 간접적으로 사용하게 됩니다.)

  • Convenience initializers. macOS 10.12에서 시작하면서, 컨트롤을 위한 편의 이니셜라이저의 풍부한 집합을 사용할 수 있습니다. 이러한 이니셜라이저들은 바 아이템의 정의를 단순화하고, 터치 바에 대한 모양과 크기를 관리합니다. 특히 NSButton, NSSegmentedControl, NSSlider 클래스는 init(title:image:target:action:)과 같은 다양한 편의 이니셜라이저를 제공합니다.

  • Text support. NSSpellChecker, NSTextField, NSTextView 클래스와 NSTextFieldDelegate NSTextViewDelegate 프로토콜에 있는 메소드 및 속성이 스펠 체크, 예측 텍스트 제안, 텍스트 완성, trailing 공간의 자동 처리를 위한 터치 바 사용을 지원합니다. 예를 들면 아래와 같습니다.

    • NSTextView 객체를 사용하는 경우 텍스트 스타일링 및 예측 텍스트 제안을 위한 자동 터치 바 지원을 얻을 수 있습니다.
    • NSCandidateListTouchBarItem 객체를 사용하는 경우 requestCandidates(forSelectedRange:in:types:options:inSpellDocumentWithTag:completionHandler:) 메소드를 사용할 수 있습니다. 이 메소드는 후보 텍스트 필터링 혹은 관리에 사용할 수 있는 컴플리션 핸들러를 제공합니다.
  • New template images. AppKitNSTouchBarItem 객채에서 사용하기 위한 다양한 새로운 템플릿 이미지를 추가합니다. touchBarAddTemplateName, touchBarComposeTemplateName, touchBarGoBackTemplateName, touchBarGoForwardTemplateName, NSImageNameTouchBarHomeTemplate입니다. 아이템에서 이미지를 위해 항상 템플릿을 사용하시기 바랍니다. 이들은 시스테 white-point 변경에 자동으로 응답합니다. 이 이미지들은 타치 바에서 사용에 대해 배타적이고, 스크린 윈도우에서는 그렇지 않습니다. 이러한 템플릿 이미지의 완전한 리스트는 NSTouchBarItem 클래스 레퍼런스의 오버뷰를 살펴보시기 바랍니다.

  • Scroll views. 팝오버 아이템을 위한 UI가 더 많은 수평 공간이 필요한 경우 스크롤 뷰(NSScrollView 클래스의 인스턴스)를 사용할 수 있습니다.이 경우 팝오버 아이템의 press-and-hold 옵션을 활성화하지 않아야 합니다. 그렇게 하는 것은 스크롤링을 방해하기 때문입니다. 스크롤 뷰에 대한 사용은 Handling Touch Events in NSTouchBarItem Objects를 살펴보시기 바랍니다.

  • Stack views. NSStackView 클래스의 인스턴스를 사용해 바 아이템을 그룹화할 수 있습니다. 그러나 이렇게 하는 것은 공간에 대한 시스템 지원을 잃습니다. 그룹 아이템(NSGroupTouchBarItem 클래스의 인스턴스)에 아이템을 위치시키는 경우 대신 시스템은 아래처럼 움직입니다.

    • inter-item 공간을 관리합니다.
    • 개별 아이템에 대해 사용자 커스터마이징을 지원합니다.

NSTouchBarItem
https://developer.apple.com/documentation/appkit/nstouchbaritem

Handling Touch Events in NSTouchBarItem Objects
https://developer.apple.com/documentation/appkit/nstouchbaritem#2647105

Development Considerations for the Touch Bar

Xcode 터치 바 시뮬레이터는 터치 바를 화면에 나타내고 몇 가지 사용자 상호작용을 지원합니다. 그러나 몇 상호작용은 시뮬레이터에서 사용이 불가능합니다. 예를 들어 터치 바 시뮬레이터에서 두 손가락 제스쳐를 수행할 수 없습니다.

앱에서 터치바 지원을 채택하는 경우이면서 터치 바 없이 맥에서 Xcode를 실행하는 경우 Xcodep에서 윈도우 > Show Touch Bar를 선택함으로써 Xcode 터치 바 시뮬레이터를 활성화할 수 있습니다.

인터페이스 빌더는 객체 라이브러리에서 사용 가능한 nib 객체와 함께 터치 바에 대한 개발을 지원합니다. 객체 라이브러리로부터 캔버스에 바 및 아이템을 드래그 앤 드롭하고, 원하는 앱 리스폰더에 붙이면 됩니다. 더 많은 정보는 Xcode Help를 보시기 바랍니다.

Performance Considerations for the Touch Bar

터치 바의 디스플레이 및 맥북 스크린은 맥북의 메인 CPU 및 GPU를 포함해서 리소스를 공유합니다. 터치 바가 더 잘 수행할 수 있도록 하려면, 앱의 메인 스레드가 과도하게 많은 것으로부터 보호해주기 위한 모범 사례를 따르시기 바랍니다. 예를 들어 메인 스레드에서 메인 디스플레이를 위한 렌더링 작업을 수행하지 않아야 합니다.

더불어 터치 바에 대한 업데이트에 상대적으로 메인 디스플레이 업데이트에 할애하는 시간의 상대적 양에 주의를 기울여야 합니다. 최적 비율은 사용자가 하는 것에 따라 달라집니다. 예를 들면 아래와 같습니다.

  • 사용자가 터치 바와 상호작용하고 있고 터치 바를 보고 있는 경우(오디오 제어가 필요한 경우처럼)에 앱이 터치바 업데이트에 대한 우선순위를 줄 수 있도록 해야 합니다.
  • 사용자가 터치 바에 상호작용하는 것 대신 메인 디스플레이를 보고 있다면(컨텐트의 페이지 브라우징을 위해 스크러버를 사용하는 경우처럼) 터치 바와 메인 디스플레이 사이에서 앱의 디스플레이 업데이트 작업을 균형있게 해줘야 합니다.

지원하는 특정 맥북 하드웨어를 사용해 터치 바 성능을 항상 테스트해야 합니다. 구체적으로 터치 바 성능에 대한 앱 튜닝을 하는 경우 Xcode 터치 바 시뮬레이터에 의존하지 않아야 합니다.

0개의 댓글