業務で絶対必要にならない技術

A77456b262557e22986345f6d0555c58?s=47 nakajijapan
January 27, 2017

 業務で絶対必要にならない技術

shibuya.swift #7

A77456b262557e22986345f6d0555c58?s=128

nakajijapan

January 27, 2017
Tweet

Transcript

  1. ۀ຿Ͱઈରඞཁ ʹͳΒͳ͍ٕज़ TIJCVZBTXJGU !OBLBKJKBQBO

  2. @nakajijapan GMO PEPABO inc. Principal Engineer iOS / Web /

    OS X About Me Daichi Nakajima
  3. ϋϯυϝΠυ࡞඼Λ ചΕΔɺങ͑Δɻ ࠃ಺࠷େڃͷ ϋϯυϝΠυϚʔέοτ

  4. NKJMultiMovieCaptureView NKJMovieComposer NKJPagerViewController PhotoSlider Teiten GitHub Sengiri Shari frustration.me Kazaguruma

  5. ۀ຿Ͱઈରඞཁ ʹͳΒͳ͍ٕज़

  6. ͦ͏

  7. ઈରʹ

  8. NSTouchBar ಋೖฤ

  9. None
  10. None
  11. NSTouchBar

  12. NSTouchBar • An object that provides dynamic contextual controls in

    the Touch Bar of supported models of MacBook Pro.
  13. NSTouchBar • Slider • Popover • Color Picker • Custom

    • NSButton, NSSegmentedControl
  14. NSTouchBar

  15. υϯͱݟ͍ͤͨςΩετΛೖΕΔ Control Strip

  16. υϯͱݟ͍ͤͨςΩετΛೖΕΔ Control Strip

  17. υϯͱݟ͍ͤͨςΩετΛೖΕΔ Control Strip

  18. Design

  19. Design • Design a contextual experience. • Use the Touch

    Bar as an extension of the keyboard and trackpad, not as a display. • Strive to match the look of the physical keyboard. • Don’t expose functionality solely in the Touch Bar. • Provide controls that produce immediate results. • Respond immediately to user interaction. • When possible, allow tasks that start in the Touch Bar to finish in the Touch Bar. • Avoid using the Touch Bar for tasks associated with well-known keyboard shortcuts. • Reflect state consistently and accurately. • Avoid mirroring Touch Bar interactions on the main screen
  20. Design • Design a contextual experience. • Use the Touch

    Bar as an extension of the keyboard and trackpad, not as a display. • Strive to match the look of the physical keyboard. • Don’t expose functionality solely in the Touch Bar. • Provide controls that produce immediate results. • Respond immediately to user interaction. • When possible, allow tasks that start in the Touch Bar to finish in the Touch Bar. • Avoid using the Touch Bar for tasks associated with well-known keyboard shortcuts. • Reflect state consistently and accurately. • Avoid mirroring Touch Bar interactions on the main screen
  21. Gesture

  22. Gesture • Tap • Touch and Hold • Horizontal swipe

    • Multitouch
  23. Sample • NSTouchBar Catalog • Shows how to create bars

    and items for use in the Touch Bar • NSToolBar Sample • Shows how to add Touch Bar support to a typical Mac app
  24. Develop

  25. Develop • Simulator͕͋Γ·͢

  26. Implementation Area

  27. Implementation Area

  28. Storyboard

  29. Storyboard • ࢹ֮తʹ഑ஔ͕Մೳ

  30. Storyboard • ࢹ֮తʹ഑ஔ͕Մೳ

  31. Identifier

  32. Identifier • Globally Unique • reverse-DNS style • should assign

    for each item
  33. Identifier fileprivate extension NSTouchBarCustomizationIdentifier { static let touchBar = NSTouchBarCustomizationIdentifier("net.nakajijapan.TouchBar")

    } fileprivate extension NSTouchBarItemIdentifier { static let play = NSTouchBarItemIdentifier(“net.nakajijapan.touchbartest001.TouchBarItem.pl ay") }
  34. NSTouchBar

  35. NSTouchBar • Be a responder (an instance of an NSResponder

    subclass) that is present within a responder chain at runtime • Conform to the NSTouchBarProvider protocol • Implement the makeTouchBar() method within that protocol
  36. NSResponder subclass • NSViewController • NSWindowController • NSView • NSWindow

    • ……
  37. Implementation override func makeTouchBar() -> NSTouchBar? { let mainBar =

    NSTouchBar() mainBar.delegate = self mainBar.customizationIdentifier = .imageViewer mainBar.defaultItemIdentifiers = [.sharingPicker, .strokePopover, .strokeColorPicker, .photoPicker, .flexibl eSpace, .clearButton, .otherItemsProxy] mainBar.customizationAllowedItemIdentifiers = [.strokeSlider, .strokePopover, .photoPicker, .strokeColorPicker, .clearBut ton, .sharingPicker, .flexibleSpace] mainBar.principalItemIdentifier = .photoPicker return mainBar }
  38. NSTouchBarDelegate @available(OSX 10.12.2, *) func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier:

    NSTouchBarItemIdentifier) -> NSTouchBarItem?
  39. AppDelegate if #available(OSX 10.12.2, *) { if ((NSClassFromString("NSTouchBar")) != nil)

    { NSApplication.shared() .isAutomaticCustomizeTouchBarMenuItemEnabled = true } }
  40. Components

  41. Button • NSCustomTouchBarItem

  42. Button • NSCustomTouchBarItem let touchBarItem = NSCustomTouchBarItem(identifier: .showWindow1) touchBarItem.customizationLabel =

    "Window" touchBarItem.view = NSButton(title: "Window", target: self, action: #selector(showWindowItemDidTap))
  43. Group Button • NSGroupCustomTouchBarItem

  44. Group Button • NSGroupCustomTouchBarItem let touchBarItem = NSCustomTouchBarItem(identifier: .showWindow1) touchBarItem.customizationLabel

    = "Window" touchBarItem.view = NSButton(title: "Window", target: self, action: #selector(changeShowWindowBySegment)) let touchBarItem2 = NSCustomTouchBarItem(identifier: .showWindow2) touchBarItem2.customizationLabel = "Window(Top)" touchBarItem2.view = NSButton(title: "Window(Top)", target: self, action: #selector(changeShowWindowBySegment)) let group = NSGroupTouchBarItem.groupItem(withIdentifier: .showWindow, items: [touchBarItem, touchBarItem2])
  45. Popover • NSPopoverTouchBarItem

  46. Popover • NSPopoverTouchBarItem let popoverItem = NSPopoverTouchBarItem(identifier: identifier) popoverItem.customizationLabel =

    "window" popoverItem.collapsedRepresentationLabel = "window" let secondaryTouchBar = NSTouchBar() secondaryTouchBar.delegate = self secondaryTouchBar.defaultItemIdentifiers = [.play]; popoverItem.pressAndHoldTouchBar = secondaryTouchBar popoverItem.popoverTouchBar = secondaryTouchBar return popoverItem
  47. Scrubber • NSScrubber • NSScrubberDelegate • NSScrubberDataSource • NSScrubberFlowLayoutDelegate

  48. Scrubber // NSScrubberDataSource func numberOfItems(for scrubber: NSScrubber) -> Int func

    scrubber(_ scrubber: NSScrubber, viewForItemAt index: Int) -> NSScrubberItemView // NSScrubberFlowLayoutDelegate func scrubber(_ scrubber: NSScrubber, layout: NSScrubberFlowLayout, sizeForItemAt itemIndex: Int) -> NSSize // NSScrubberDelegate func scrubber(_ scrubber: NSScrubber, didSelectItemAt index: Int)
  49. SharingService • NSSharingServicePickerTouchBarItem

  50. SharingService • NSSharingServicePickerTouchBarItem // MARK: - NSSharingServicePickerTouchBarItemDelegate extension WindowController: NSSharingServicePickerTouchBarItemDelegate

    { @available(OSX 10.12.2, *) func items(for pickerTouchBarItem: NSSharingServicePickerTouchBarItem) -> [Any] { return [NSImage(named: NSImageNameTouchBarRecordStartTemplate)!] } } let services = NSSharingServicePickerTouchBarItem(identifier: identifier) services.delegate = self
  51. ͸·ΓϙΠϯτ

  52. ࣗલͷΞϓϦʹೖΕͯΈͨ • Sengiri • ը໘Ωϟϓνϟͨ͠ΒࣗಈతʹGIFʹม׵ • Teiten • PCͷΧϝϥΛར༻ͯ͠ͻͨ͢Βఆ఺؍ଌ

  53. Sengiri

  54. Let’s TRY!!!

  55. None
  56. None
  57. None
  58. “I have no idea” • NSWindowControllerΛopenͤͨ࣌͞ʹ makeTouchBar()͕callͯ͘͠Εͳ͍

  59. if let windowController = storyBoard.instantiateController(withIdentifier: "CaptureWindowController") as? CaptureWindowController { captureController

    = windowController windowController.showWindow(nil) }
  60. if let windowController = storyBoard.instantiateController(withIdentifier: "CaptureWindowController") as? CaptureWindowController { captureController

    = windowController windowController.showWindow(nil) } NSTouchBarͷ࣮૷͸͍ͨͬͯ௨ৗ
  61. if let windowController = storyBoard.instantiateController(withIdentifier: "CaptureWindowController") as? CaptureWindowController { captureController

    = windowController windowController.showWindow(nil) } WindowΛಁ໌ʹ͍ͯ͠Δ͜ͱ͕ݪҼ ʁʁʁ
  62. None
  63. None
  64. ҰߦͣͭίϝϯτΞ΢τ

  65. override init(contentRect: NSRect, styleMask aStyle: NSWindowStyleMask, backing bufferingType: NSBackingStoreType, defer

    flag: Bool) { super.init(contentRect: contentRect, styleMask: aStyle, backing: bufferingType, defer: flag) isReleasedWhenClosed = true displaysWhenScreenProfileChanges = true backgroundColor = NSColor.clear isOpaque = false hasShadow = false collectionBehavior = [.fullScreenPrimary] isMovable = true isMovableByWindowBackground = true styleMask = [NSBorderlessWindowMask, NSResizableWindowMask] ignoresMouseEvents = false level = Int(CGWindowLevelForKey(.floatingWindow)) NotificationCenter.default.addObserver(self, selector: #selector(recordButtonDidClick(_:)), name: NSNotification.Name(rawValue: "CaptureViewRecordButtonDidClick"), object: nil) setFrame(NSRect(x: 200, y: 200, width: 500, height: 500), display: true) NSEvent.addLocalMonitorForEvents(matching: .keyDown) { (aEvent) -> NSEvent? in self.keyDown(with: aEvent) return aEvent } }
  66. override init(contentRect: NSRect, styleMask aStyle: NSWindowStyleMask, backing bufferingType: NSBackingStoreType, defer

    flag: Bool) { super.init(contentRect: contentRect, styleMask: aStyle, backing: bufferingType, defer: flag) isReleasedWhenClosed = true displaysWhenScreenProfileChanges = true backgroundColor = NSColor.clear isOpaque = false hasShadow = false collectionBehavior = [.fullScreenPrimary] isMovable = true isMovableByWindowBackground = true styleMask = [NSBorderlessWindowMask, NSResizableWindowMask] ignoresMouseEvents = false level = Int(CGWindowLevelForKey(.floatingWindow)) NotificationCenter.default.addObserver(self, selector: #selector(recordButtonDidClick(_:)), name: NSNotification.Name(rawValue: "CaptureViewRecordButtonDidClick"), object: nil) setFrame(NSRect(x: 200, y: 200, width: 500, height: 500), display: true) NSEvent.addLocalMonitorForEvents(matching: .keyDown) { (aEvent) -> NSEvent? in self.keyDown(with: aEvent) return aEvent } } ݪҼ͸෼͔Βͣɻɻɻ
  67. UI͸ͦΕʹ୅ସͰ͖Δ΋ͷ͕Ͱ͖ͨ

  68. Complete!!

  69. ࿥ը͍ͯ͠Δ࣌͸ϑΥʔΧε͕ผͷ ΞϓϦʹ͋ͨΔͷͰͦͷΞϓϦͷ TouchBarItemʹͳͬͯ͠·͏ͨΊStop ͕Ͱ͖ͳ͍ͷͰશ͘ҙຯ௕͍…

  70. Teiten

  71. ReTRY!!!!

  72. None
  73. It’s a simple..

  74. Conlusion

  75. Conclusion • ͦΕ୯ମͰ׬ྃ͢ΔλεΫʹదԠ͢Δ • WindowΛಁ໌ʹ͢ΔͱNSTouchBar͕൓Ԡ͠ ͳ͍ • ݪҼΘ͔Βͣɾɾɾ

  76. Conclusion • ͦΕ୯ମͰ׬ྃ͢ΔλεΫʹదԠ͢Δ • WindowΛಁ໌ʹ͢ΔͱNSTouchBar͕൓Ԡ͠ ͳ͍ • ݪҼΘ͔Βͣɾɾɾ • ۀ຿Ͱ͸ઈର࢖Θͳ͍ٕज़

  77. MacBook Pro ΄͍͠

  78. Thanks.