3

파인더 및 노트에는 재현하려는 고유 한 동작이 있습니다. NSToolbar의 '유연한 공간'은 분할보기의 크기를 고려한 것 같습니다. 예를 들어, 첫 번째 단추 그룹은 왼쪽에 세로 막대의 오른쪽에 정렬됩니다. 두 번째 아이콘 그룹은 첫 번째 열의 오른쪽에 정렬됩니다. 사이드 바를 넓힐 때 도구 모음 항목이 함께 이동합니다.NSSplitView 열로 NSToolbarItem을 정렬하십시오.

이것을 재현 할 수 있습니까?

final class MainWindowController: NSWindowController { 
    override func windowDidLoad() { 
     super.windowDidLoad() 
     window?.toolbar?.delegate = self 
     // Make sure that tracking is enabled when the toolbar is completed 
     DispatchQueue.main.async { 
      self.trackSplitViewForFirstFlexibleToolbarItem() 
     } 
    } 
} 

extension MainWindowController: NSToolbarDelegate { 
    func toolbarWillAddItem(_ notification: Notification) { 
     // Make sure that tracking is evaluated only after the item was added 
     DispatchQueue.main.async { 
      self.trackSplitViewForFirstFlexibleToolbarItem() 
     } 
    } 

    func toolbarDidRemoveItem(_ notification: Notification) { 
     trackSplitViewForFirstFlexibleToolbarItem() 
    } 

    /// - Warning: This is a private Apple method and may break in the future. 
    func toolbarDidReorderItem(_ notification: Notification) { 
     trackSplitViewForFirstFlexibleToolbarItem() 
    } 

    /// - Warning: This method uses private Apple methods that may break in the future. 
    fileprivate func trackSplitViewForFirstFlexibleToolbarItem() { 
     guard var toolbarItems = self.window?.toolbar?.items, let splitView = (contentViewController as? NSSplitViewController)?.splitView else { 
      return 
     } 

     // Add tracking to the first flexible space and remove it from the group 
     if let firstFlexibleToolbarItem = toolbarItems.first, firstFlexibleToolbarItem.itemIdentifier == NSToolbarFlexibleSpaceItemIdentifier { 
      _ = firstFlexibleToolbarItem.perform(Selector(("setTrackedSplitView:")), with: splitView) 
      toolbarItems.removeFirst() 
     } 

     // Remove tracking from other flexible spaces 
     for flexibleToolbarItem in toolbarItems.filter({ $0.itemIdentifier == NSToolbarFlexibleSpaceItemIdentifier }) { 
      _ = flexibleToolbarItem.perform(Selector(("setTrackedSplitView:")), with: nil) 
     } 
    } 
} 

답변

2

당신은 애플 민간 방법으로이 작업을 수행 할 수 있지만, :

enter image description here


@KenThomases가 제공하는 솔루션으로 해결

다음과 같이 내가 이것을 구현 그것은 App Store에서 허용되지 않습니다.

NSToolbarItem에 비공개 방법 인 -setTrackedSplitView:이 있습니다. 매개 변수로 NSSplitView*이 필요합니다. 분할 된 뷰를 추적하고 추적해야하는 분할 뷰를 전달하려는 유연한 공간 툴바 항목에서이 뷰를 호출해야합니다. Apple이 방법을 제거하지 못하도록하려면 사용하기 전에 NSToolbarItem이 해당 방법에 응답하는지 확인해야합니다.

사용자가 도구 모음을 사용자 지정하고 순서를 변경할 수 있으므로 일반적으로 창의 도구 모음 항목을 열거해야합니다. 식별자가 NSToolbarFlexibleSpaceItemIdentifier 인 첫 번째 항목의 경우 추적 할 분할보기를 설정합니다. 다른 모든 가변 공간 항목의 경우 추적 할 분할보기를 지우 (nil으로 설정)합니다. 도구 모음 대리인의 -toolbarWillAddItem:-toolbarDidRemoveItem: 메쏘드에서 창을 처음 다시 설정하고 다시 설정할 때 그렇게해야합니다. 또 다른 문서화되지 않은 대리자 메서드 인 -toolbarDidReorderItem:이 있는데 여기서는 툴바를 업데이트하는 것이 유용하다는 것을 알았습니다.

+0

환상적입니다. 두 가지 설명 : (1)'toolbarWillAddItem :'은이 메소드가 호출 될 때 툴바 아이템이 업데이트되지 않기 때문에 약간 다른 동작이 필요합니다. 대신'setTrackedSplitView :'이이 네트 아이템에 직접 호출되어야한다. (2) 나머지 항목을 nil로 설정하면 비정상적인 동작이 발생하고 '인식 할 수없는 선택자'종류의 오류가 발생합니다. – Eitot

+1

나머지 ** flexible space ** 항목은'nil'을 추적하도록 설정해야합니다. 후드 아래에는 해당 항목에 대한 특정 하위 클래스가 있다고 가정합니다. 이전에 추적 뷰를 설정 한 다음 순서를 변경했기 때문에 추적 된 분할 뷰를 지울 필요가 있습니다. '-toolbarWillAddItem :'과 관련하여, 필자의 코드는 메인 쓰레드에'dispatch_async()'를 사용하여 실행 루프 사이클의 끝까지 아이템의 업데이트를 연기한다. –

+0

'DispatchQueue.main.async()'에서 호출하는 것은 응용 프로그램이 실행 중일 때만 내 코드에서 작동하지만 시작시에는 작동하지 않는 것 같습니다. 이것을 구현 한 예를 들어 주시겠습니까? – Eitot