macOS Catalystのメニュー対応 #hakataswift #love_swift/menu_for_macos_catalyst

249b3122eee454c0a818bfe7851418e4?s=47 fromkk
January 25, 2020

macOS Catalystのメニュー対応 #hakataswift #love_swift/menu_for_macos_catalyst

この資料は第11回 HAKATA.swift x Swift愛好会~福岡と東京のSwift勉強会コラボ~( https://hakata-swift.connpass.com/event/149988/ )にて登壇してきたLTの資料です。

概要
WWDC 2019にてmacOS Catalystが発表され、iPadアプリをmacOSアプリ化することができるようになりました。
UIKitが利用できるのでこれまでiOSアプリを開発してきた技術がそのまま利用が可能になります。
少ない工数で配布できるプラットフォームが増えるのでビジネス的にもチャンスが広がるかと思います。
ここではiOS向けアプリケーションには無くてmacOS向けアプリケーションのUIコンポーネントにあるメニューの実装方法について紹介します。

249b3122eee454c0a818bfe7851418e4?s=128

fromkk

January 25, 2020
Tweet

Transcript

  1. NBD04$BUBMZTUͷϝχϡʔରԠ )","5"TXJGUY4XJGUѪ޷ձ 1

  2. 1SPpMF struct Profile { let name = "Kazuya Ueoka" let

    twitter = "@fromkk" let github = "fromkk" let qiita = "fromkk" let company = "Timers Inc." } • 2
  3. NBD04$BUBMZTU΍ͬͯΔਓʁ 3

  4. NBD04$BUBMZTUͱ͸ w 88%$Ͱൃද͞ΕͨJ1BE04޲͚ͷΞϓϦΛNBD04޲ ͚ʹϏϧυՄೳʹ͢Δٕज़ w 6*,JU͕ར༻Ͱ͖ΔͷͰJ04Ͱഓ͖ٕͬͯͨज़͕ͦͷ··ར༻Մ ೳ w গͳ͍޻਺Ͱ഑෍Ͱ͖ΔϓϥοτϑΥʔϜ͕૿͑ΔͷͰϏδω εతʹ΋νϟϯε

    4
  5. w 9DPEFͷ(FOFSBMλϒͷ%FQMPZNFOU*OGPͰ.BDʹνΣοΫΛ ೖΕΔ͚ͩ ରԠํ๏ 5

  6. J04ͱNBD04ͷେ͖ͳҧ͍ w λΠτϧόʔ 6

  7. J04ͱNBD04ͷେ͖ͳҧ͍ w λΠτϧόʔ  w πʔϧόʔ 7

  8. J04ͱNBD04ͷେ͖ͳҧ͍ w λΠτϧόʔ  w πʔϧόʔ  w 5PVDI#BS 8

  9. J04ͱNBD04ͷେ͖ͳҧ͍ w λΠτϧόʔ  w πʔϧόʔ  w 5PVDI#BS 

    w ϝχϡʔ 9
  10. w λΠτϧόʔ  w πʔϧόʔ  w 5PVDI#BS  w

    ϝχϡʔ J04ͱNBD04ͷେ͖ͳҧ͍ 10
  11. w "QQ%FMFHBUF 6*3FTQPOEFS ʹCVJME.FOVͱ͍͏ϝιου͕ ͍ΔͷͰ࣮૷ΛՃ͑Δ w CVJMEFSTZTUFNʹDPOUFYUͷछྨ͕౉͞ΕΔͷͰϋϯυϦϯά ͢Δ ࣮૷ํ๏ #if

    targetEnvironment(macCatalyst) override func buildMenu(with builder: UIMenuBuilder) { super.buildMenu(with: builder) // TODO: build your menu } #endif IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJSFTQPOEFSCVJMENFOV 11
  12. 6*.FOV4ZTUFN w Ͳ͏͍͏࣌ʹݺ͹Ε͔ͨɺϝχϡʔΛ࠶ߏங͢Δඞཁ͕͋Δ͔ ͳͲͷ৘ใΛอ͍࣋ͯ͠Δ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJNFOVTZTUFN 12 UIMenuSystem ఆٛ .main ΞϓϦىಈ࣌ʹ౉͞ΕΔɻΞϓϦશମͷϝχϡʔΛߏங͢Δࡍʹར༻͢Δɻ

    .context ӈΫϦοΫϝχϡʔ(contextMenu)͕දࣔ͞ΕΔࡍʹ౉͞ΕΔɻ
  13. 6*.FOV w ϝχϡʔΛߏ੒͢ΔΫϥε w λΠτϧ΍ը૾Λઃఆ͢Δ͜ͱ͕Ͱ͖Δ w DIJMESFOʹ͸6*.FOV&MFNFOUΛܧঝ͍ͯ͠ΔΫϥεΛೖΕΔ͜ͱ͕Ͱ͖ΔͷͰ࠶ؼ తʹϝχϡʔΛ࡞Δ͜ͱ͕Մೳ w ˢͷ͕ͭ6*.FOVɺ಺෦͸6*.FOV&MFNFOUͷDIJMESFO

    w BDUJPO4FMFDUPS͸࣮ߦՄೳͳ!PCKDͳϝιουΛࢦఆՄೳ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJNFOV init(title: String, image: UIImage? = nil, identifier: UIMenu.Identifier? = nil, options: UIMenu.Options = [], children: [UIMenuElement] = []) 13
  14. 6*.FOV#VJMEFS w ϝχϡʔͷߏ੒Λ؅ཧ͢ΔΫ ϥε w ϝχϡʔͷ௥Ճɺ࡟আɺೖΕ ସ͕͑Մೳ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJNFOVCVJMEFS /// Replace

    an identified menu with a menu. /// /// @param replacedIdentifier The identifier of the menu to be replaced. /// @param replacementGroup The replacement menu. func replace(menu replacedIdentifier: UIMenu.Identifier, with replacementMenu: UIMenu) /// Replace the children of an identified parent menu. /// /// @param parentIdentifier The identifier of the parent menu. /// @param childrenBlock A block that returns the new children, given the old children. func replaceChildren(ofMenu parentIdentifier: UIMenu.Identifier, from childrenBlock: ([UIMenuElement]) -> [UIMenuElement]) /// Insert a sibling menu before an identified sibling menu. /// /// @param siblingGroup The sibling menu to insert. /// @param siblingIdentifier The identifier of the sibling menu to insert before. func insertSibling(_ siblingMenu: UIMenu, beforeMenu siblingIdentifier: UIMenu.Identifier) /// Insert a sibling menu before an identified sibling menu. /// /// @param siblingGroup The sibling menu to insert. /// @param siblingIdentifier The identifier of the sibling menu to insert before. func insertSibling(_ siblingMenu: UIMenu, afterMenu siblingIdentifier: UIMenu.Identifier) /// Insert a child menu at the start of an identified parent menu. /// /// @param childGroup The child menu to insert. /// @param parentIdentifier The identifier of the parent menu to insert at the start of. func insertChild(_ childMenu: UIMenu, atStartOfMenu parentIdentifier: UIMenu.Identifier) /// Insert a child menu at the end of an identified parent menu. /// /// @param childGroup The child menu to insert. /// @param parentIdentifier The identifier of the parent menu to insert at the end of. func insertChild(_ childMenu: UIMenu, atEndOfMenu parentIdentifier: UIMenu.Identifier) /// Remove an identified menu. /// /// @param removedIdentifier The menu to remove. func remove(menu removedIdentifier: UIMenu.Identifier) 14
  15. 6*"DUJPO w Ϋϩʔδϟʔ CMPDLT Λݺͼग़ͤΔ w 6*.FOV&MFNFOUΛܧঝ͍ͯ͠ΔͷͰ6*.FOVͷDIJMESFOʹ௥ Ճ͢Δ͜ͱ͕Ͱ͖Δ 15 IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJBDUJPO

    public convenience init(title: String, image: UIImage? = nil, identifier: UIAction.Identifier? = nil, discoverabilityTitle: String? = nil, attributes: UIMenuElement.Attributes = [], state: UIMenuElement.State = .off, handler: @escaping UIActionHandler)
  16. 6*$PNNBOE w ηϨΫλʔΛݺͼग़ͤΔ w 6*.FOV&MFNFOUΛܧঝ͍ͯ͠ΔͷͰ6*.FOVͷDIJMESFOʹ௥ Ճ͢Δ͜ͱ͕Ͱ͖Δ 16 IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJDPNNBOE public convenience

    init(title: String, image: UIImage? = nil, action: Selector, propertyList: Any? = nil, alternates: [UICommandAlternate] = [], discoverabilityTitle: String? = nil, attributes: UIMenuElement.Attributes = [], state: UIMenuElement.State = .off)
  17. 6*,FZ$PNNBOE w ΩʔϘʔυγϣʔτΧοτΛՄೳʹ͢ΔΫϥε w 6*$PNNBOEΛܧঝ͍ͯ͠ΔͷͰ6*.FOVͷDIJMESFOʹ௥Ճ͢ Δ͜ͱ͕Ͱ͖Δ 17 IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJLFZDPNNBOE

  18. DBO1FSGPSN"DUJPO @XJUI4FOEFS w ౉͞ΕͨBDUJPO͕࣮ߦՄೳ͔ #PPM Λฦ͢ w ϝχϡʔͷ׆ੑɺඇ׆ੑΛ൑ఆ 18 IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJSFTQPOEFSDBOQFSGPSNBDUJPO

  19. ॴײ w ஫ҙ఺ͱͯ͠͸CVJME.FOV͕ݺ͹Εͨ࣌఺ͰඞཁͳΠϯελϯε͕ ແ͍Մೳੑ͕ߴ͍ͷͰϝχϡʔͷΠϯελϯεΛ੩తʹอ͓࣋ͯ͘͠ ඞཁ͕͋Δ w جຊతʹΞϓϦͷىಈ࣌ʹϝχϡʔΛܾΊͯ͠·͏ඞཁ͕͋Γͦ͏ w BDUJPO4FMFDUPS͸ॏෳΛڐ͞ͳ͍ͷͰҰҙʹͯ͠΍Δඞཁ͕͋Δ w

    "QQMFެࣜͷαϯϓϧίʔυ͕͋ΔͷͰͱͯ΋ࢀߟʹͳͬͨ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJDPNNBOEBEEJOH@NFOVT@BOE@TIPSUDVUT@UP@UIF@NFOV@CBS@BOE@VTFS@JOUFSGBDF 19
  20. ·ͱΊ w J04Ͱ͸શ͘ҙࣝͯ͜͠ͳ͔͚ͬͨͲ.BDͰ͸ΩʔϘʔυ γϣʔτΧοτͱಉ༷ʹϝχϡʔ΋ͱͯ΋େࣄͳཁૉͩͱ࣮ײ ͨ͠ w ࠓޙ$BUBMZTUରԠ͢Δ৔߹ʹ͸ରԠ͕ϚετʹͳΓͦ͏ w ࡉ͔͍ϝχϡʔΛ࡞ΓࠐΜͰΑΓྑ͍$BUBMZTUΞϓϦΛ࡞ͬͯ ͍͖·͠ΐ͏

    20
  21. 13 21

  22. ʲిࢠॻ੶ʳNBD04$BUBMZTU%FFQ%JWF 22 IUUQTGSPNLLCPPUIQNJUFNT

  23. • αʔόʔαΠυΤϯδχΞ (PHP, Golang, AWS) • AndroidΤϯδχΞ (Kotlin) • iOSΤϯδχΞ

    (Swift) TimersͰ͸ݱࡏΤϯδχΞશ৬छ࠾༻தʂ ৄ͘͠͸”Timers”Ͱݕࡧ 23
  24. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ 24