Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

nakajijapan
January 27, 2017

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

shibuya.swift #7

nakajijapan

January 27, 2017
Tweet

More Decks by nakajijapan

Other Decks in Technology

Transcript

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

    View full-size slide

  2. @nakajijapan
    GMO PEPABO inc.
    Principal Engineer
    iOS / Web / OS X
    About Me
    Daichi Nakajima

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  6. NSTouchBar
    ಋೖฤ

    View full-size slide

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

    View full-size slide

  8. NSTouchBar
    • Slider
    • Popover
    • Color Picker
    • Custom
    • NSButton, NSSegmentedControl

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  12. 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

    View full-size slide

  13. 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

    View full-size slide

  14. Gesture
    • Tap
    • Touch and Hold
    • Horizontal swipe
    • Multitouch

    View full-size slide

  15. 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

    View full-size slide

  16. Develop
    • Simulator͕͋Γ·͢

    View full-size slide

  17. Implementation Area

    View full-size slide

  18. Implementation Area

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  21. Identifier
    • Globally Unique
    • reverse-DNS style
    • should assign for each item

    View full-size slide

  22. Identifier
    fileprivate extension NSTouchBarCustomizationIdentifier {
    static let touchBar =
    NSTouchBarCustomizationIdentifier("net.nakajijapan.TouchBar")
    }
    fileprivate extension NSTouchBarItemIdentifier {
    static let play =
    NSTouchBarItemIdentifier(“net.nakajijapan.touchbartest001.TouchBarItem.pl
    ay")
    }

    View full-size slide

  23. 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

    View full-size slide

  24. NSResponder subclass
    • NSViewController
    • NSWindowController
    • NSView
    • NSWindow
    • ……

    View full-size slide

  25. 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
    }

    View full-size slide

  26. NSTouchBarDelegate
    @available(OSX 10.12.2, *)
    func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier:
    NSTouchBarItemIdentifier) -> NSTouchBarItem?

    View full-size slide

  27. AppDelegate
    if #available(OSX 10.12.2, *) {
    if ((NSClassFromString("NSTouchBar")) != nil) {
    NSApplication.shared()
    .isAutomaticCustomizeTouchBarMenuItemEnabled = true
    }
    }

    View full-size slide

  28. Button
    • NSCustomTouchBarItem

    View full-size slide

  29. Button
    • NSCustomTouchBarItem
    let touchBarItem = NSCustomTouchBarItem(identifier: .showWindow1)
    touchBarItem.customizationLabel = "Window"
    touchBarItem.view = NSButton(title: "Window", target: self, action:
    #selector(showWindowItemDidTap))

    View full-size slide

  30. Group Button
    • NSGroupCustomTouchBarItem

    View full-size slide

  31. 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])

    View full-size slide

  32. Popover
    • NSPopoverTouchBarItem

    View full-size slide

  33. 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

    View full-size slide

  34. Scrubber
    • NSScrubber
    • NSScrubberDelegate
    • NSScrubberDataSource
    • NSScrubberFlowLayoutDelegate

    View full-size slide

  35. 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)

    View full-size slide

  36. SharingService
    • NSSharingServicePickerTouchBarItem

    View full-size slide

  37. 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

    View full-size slide

  38. ͸·ΓϙΠϯτ

    View full-size slide

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

    View full-size slide

  40. Let’s TRY!!!

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  44. if let windowController =
    storyBoard.instantiateController(withIdentifier:
    "CaptureWindowController") as? CaptureWindowController {
    captureController = windowController
    windowController.showWindow(nil)
    }
    WindowΛಁ໌ʹ͍ͯ͠Δ͜ͱ͕ݪҼ
    ʁʁʁ

    View full-size slide

  45. ҰߦͣͭίϝϯτΞ΢τ

    View full-size slide

  46. 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
    }
    }

    View full-size slide

  47. 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
    }
    }
    ݪҼ͸෼͔Βͣɻɻɻ

    View full-size slide

  48. UI͸ͦΕʹ୅ସͰ͖Δ΋ͷ͕Ͱ͖ͨ

    View full-size slide

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

    View full-size slide

  50. It’s a simple..

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  53. MacBook Pro
    ΄͍͠

    View full-size slide