Let's Coding SwiftUI on iPad!

Let's Coding SwiftUI on iPad!

第11回 HAKATA.swift x Swift愛好会~福岡と東京のSwift勉強会コラボ~
https://hakata-swift.connpass.com/event/149988/

D36d6bab8f1e0ff4bb3377571e5f7dcd?s=128

Yutaro Muta

January 25, 2020
Tweet

Transcript

  1. Let's Coding SwiftUI on iPad! 2020/01/21 @HAKATA.swift vol.11 Yutaro Muta

    @yutailang0119
  2. • Yutaro Muta @yutailang0119 • Hatena Co., Ltd. @Kyoto •

    Conference Staff • builderscon 2020 • try! Swift Tokyo 2020 • and more Who am I ?
  3. Goal • iPadͰίʔσΟϯά͢ΔΑ͏ʹͳΔ • ͍࣋ͬͯͳ͍ਓ͸iPadΛങͬͯؼΔ • SwiftUIͷViewʹ͍ͭͯɺͪΐͬͱ஌Δ

  4. What's Swift Playgrounds?

  5. What's Swift Playgrounds? • iPadΞϓϦ Swift Playground • Document: https://developer.apple.com/documentation/swift_playgrounds

    • ϝΠϯϢʔε͸ɺϓϩάϥϛϯάڭҭΒ͍͠
  6. What's Swift Playgrounds? • iOSΞϓϦ։ൃͱ͍ۙ͠ػೳ͕ଟ͘࢖͑Δ • UIKit (Xcode Playground) •

    Camera • Bluetooth • AR (SceneKit) • SwiftUI ΋࢖͑Δʂʂʂʂʂ • Swift Playgrounds 3.1: Build with the SwiftUI framework in new playgrounds you create
  7. Run SwiftUI on Swift Playgrounds

  8. Run SwiftUI on Swift Playgrounds import SwiftUI import PlaygroundSupport struct

    ContentView: View { var body: some View { VStack { Text("Hello") .font(.largeTitle) .foregroundColor(.primary) Text("world") .font(.title) .foregroundColor(.secondary) } } } let host = UIHostingController(rootView: ContentView()) PlaygroundPage.current.liveView = host
  9. Run SwiftUI on Swift Playgrounds

  10. Run Swift Playgrounds file on Xcode

  11. Run Swift Playgrounds file on Xcode • PlaygroundsͷStarting Pointʹ Xcode

    PlaygroundΛબ୒͢Δ • ֦ுࢠ͕ .playgroundͱͯ͠࡞੒͞ΕΔ (্هҎ֎ͩͱ .playgroundbook) -> XcodeͷPlaygroundͰ΋࣮ߦ͕Ͱ͖Δ • ٯʹɺXcodeͰ࡞੒ͨ͠ .playground ΋Swift PlaygroundsͰ࣮ߦՄೳ
  12. Run Swift Playgrounds file on Xcode

  13. Pros/Cons of Swift Playgrounds

  14. Pros of Swift Playgrounds • iPadͰखܰʹίʔυ͕ॻ͚Δ • Foundation΋SwiftUI΋ͦΕҎ֎ͷFramework΋ѻ͑Δ • ΦϑϥΠϯͰ࣮ߦՄೳ

  15. Cons of Swift Playgrounds • Xcodeʹൺ΂ΔͱɺΤσΟλ͸෺଍Γͳ͍ • ίϯύΠϧ • ૣ͘͸ͳ͍

    • XcodeͷSwiftUI Canvas͸ͳ͍ • ຖճ࣮ߦ͕ඞཁ • UIHostingControllerʹೖΕͨ1ͭViewΛ஫ࢹ͢Δ͜ͱʹͳΔ
  16. ͓͠·͍

  17. ⚡͔͜͜Βຊฤ⚡

  18. Cons of Swift Playgrounds • Xcodeʹൺ΂ΔͱɺΤσΟλ͸෺଍Γͳ͍ • ίϯύΠϧ • ૣ͘͸ͳ͍

    • XcodeͷSwiftUI Canvas͸ͳ͍ • ຖճ࣮ߦ͕ඞཁ • UIHostingControllerʹೖΕͨ1ͭViewΛ஫ࢹ͢Δ͜ͱʹͳΔ
  19. Cons of Swift Playgrounds • Xcodeʹൺ΂ΔͱɺΤσΟλ͸෺଍Γͳ͍ • ίϯύΠϧ • ૣ͘͸ͳ͍

    • XcodeͷSwiftUI Canvas͸ͳ͍ • ຖճ࣮ߦ͕ඞཁ • UIHostingControllerʹೖΕͨ1ͭViewΛ஫ࢹ͢Δ͜ͱʹͳΔ <- AppleཔΉ
  20. Cons of Swift Playgrounds • Xcodeʹൺ΂ΔͱɺΤσΟλ͸෺଍Γͳ͍ • ίϯύΠϧ • ૣ͘͸ͳ͍

    • XcodeͷSwiftUI Canvas͸ͳ͍ • ຖճ࣮ߦ͕ඞཁ • UIHostingControllerʹೖΕͨ1ͭViewΛ஫ࢹ͢Δ͜ͱʹͳΔ <- AppleཔΉ
  21. Cons of Swift Playgrounds • Xcodeʹൺ΂ΔͱɺΤσΟλ͸෺଍Γͳ͍ • ίϯύΠϧ • ૣ͘͸ͳ͍

    • XcodeͷSwiftUI Canvas͸ͳ͍ • ຖճ࣮ߦ͕ඞཁ • UIHostingControllerʹೖΕͨ1ͭViewΛ஫ࢹ͢Δ͜ͱʹͳΔ <- AppleཔΉ
  22. Cons of Swift Playgrounds • Xcodeʹൺ΂ΔͱɺΤσΟλ͸෺଍Γͳ͍ • ίϯύΠϧ • ૣ͘͸ͳ͍

    • XcodeͷSwiftUI Canvas͸ͳ͍ • ຖճ࣮ߦ͕ඞཁ • UIHostingControllerʹೖΕͨ1ͭViewΛ஫ࢹ͢Δ͜ͱʹͳΔ ^ | Ͳ͏ʹ͔Ͱ͖ͦ͏
  23. yutailang0119/LayoutInspector ໊લ͸෇͚͍ͯΔ͚Ͳɺ·ͩͰ͖ͯͳ͍

  24. LayoutInspector

  25. LayoutInspector import SwiftUI struct LayoutInspector<Body: View>: View { private let

    _body: Body private let color: Color init(body: Body, color: Color? = nil) { self._body = body self.color = color ?? Color.random } var body: some View { ZStack(alignment: .topLeading) { self._body .layoutPriority(1.0) self._label } .border(color) } private var _label: some View { Text(String(describing: type(of: _body))) .lineLimit(1) .font(.footnote) .foregroundColor(.primary) .background(color.opacity(0.7)) } } import SwiftUI extension SwiftUI.View { func layoutInspector(color: Color? = nil) -> some View { LayoutInspector(body: self, color: color) } }
  26. LayoutInspector

  27. ׬ᘳ

  28. < ViewModifier protocolʹ ४ڌ͢ΔͱΑͦ͞͏ͩΑ

  29. ViewModifier • https://developer.apple.com/documentation/swiftui/viewmodifier > A modifier that you apply to

    a view or another view modifier, producing a different version of the original value. • ModifiedContent ΍ View.modifier(_:) ͱ૊Έ߹Θͤͯ࢖͏
  30. Custom ViewModifier import SwiftUI struct PrimaryLabel: ViewModifier { func body(content:

    Content) -> some View { content .padding() .background(Color.red) .foregroundColor(Color.white) .font(.largeTitle) } } HACKING WITH Swift: How to create custom modifiers https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-custom-modifiers
  31. Extension SwiftUI.View import SwiftUI extension SwiftUI.View { func labelPrimary() ->

    some View { self .modifier(PrimaryLabel()) } }
  32. Custom ViewModifier

  33. ͳΔ΄ͲɺΑͦ͞͏ͩ

  34. ݁࿦͔Βݴ͏ͱɺେมͩͬͨ

  35. ModifierΛ࡞ͬͯɺ ಺෦ͰLayoutInspectorΛ࢖ͬͯΈΔ

  36. LayoutInspectModifier (α) struct LayoutInspectModifier: ViewModifier { private let color: Color?

    init(color: Color? = nil) { self.color = color } public func body(content: Content) -> some View { LayoutInspector(body: content, color: color) } }
  37. LayoutInspectModifier (α)

  38. _ViewModifier_Content<LayoutInspectorModifier> LayoutInspectModifier (α)

  39. ViewModifierͷ࣮૷ • func body(content: Self.Content) -> Self.Body • Gets the

    current body of the caller. • Discussion • content is a proxy for the view that will have the modifier represented by Self applied to it. • typealias ViewModifier.Content • The content view type.
  40. ViewModifierͷ࣮૷ • ViewModifier.Content ͸ɺݩͷViewͦͷ΋ͷͰ͸ͳ͘ɺProxy • contentʹ type(of:) Λ͔͚ͯ΋ɺݩͷViewͷType͸Θ͔Βͳ͍

  41. OMG

  42. ࡞ઓมߋ • ModifierΛ෼͚Δ • ֎࿮ͱ೚ҙͷϥϕϧΛ෇͚Δ LayoutInspectModifier • ֎࿮Λ෇͚ͭͭɺType໊Λදࣔ͢Δ TypeNameLayoutInspectModifier

  43. LayoutInspecterΛมߋ

  44. LayoutInspecter import SwiftUI struct LayoutInspector<Body: View>: View { private let

    _body: Body private let label: String private let color: Color init(body: Body, label: String, color: Color? = nil) { self._body = body self.label = label self.color = color ?? Color.random } var body: some View { ZStack(alignment: .topLeading) { self._body .layoutPriority(1.0) self._label } .border(color) } private var _label: some View { Text(label) .lineLimit(1) .font(.footnote) .foregroundColor(.primary) .background(color.opacity(0.7)) } }
  45. LayoutInspectModifier

  46. LayoutInspectModifier import SwiftUI struct LayoutInspectModifier: ViewModifier { private let color:

    Color? private let label: String init(color: Color? = nil, label: String = "") { self.color = color self.label = label } func body(content: Content) -> some View { LayoutInspector(body: content, label: label, color: color) } }
  47. TypeNameLayoutInspectModifier

  48. TypeNameLayoutInspectModifier import SwiftUI struct TypeNameLayoutInspectModifier<V: View>: ViewModifier { private let

    color: Color? private let _body: V init(color: Color? = nil, body: V) { self.color = color self._body = body } func body(content: Content) -> some View { LayoutInspector(body: content, label: String(describing: type(of: _body)), color: color) } }
  49. ModifierΛద༻͢Δextension import SwiftUI extension SwiftUI.View { func layoutInspector(color: Color? =

    nil, label: String = "") -> some View { self .modifier(LayoutInspectModifier(color: color, label: label)) } func typeNameLayoutInspector(color: Color? = nil) -> some View { self .modifier(TypeNameLayoutInspectModifier(color: color, body: self)) } }
  50. ࣮ߦʂ

  51. ࣮ߦʂ

  52. Αͦ͞͏

  53. ࣮͸·ͩམͱ͕݀͠...

  54. contentView.frame()

  55. ViewModifierΛܦ༝͢ΔViewʹ TypeNameLayoutInspectModifier͸ ΍ͬͺΓյΕΔ

  56. ࠓ೔͸͜͜·Ͱ

  57. ·ͱΊ

  58. ·ͱΊ • iPad͚ͩͰ΋ɺSwiftɺSwiftUIΛॻ͘͜ͱ͸Ͱ͖Δ • yutailang0119/LayoutInspector ͸ɺ΋͏ͪΐͬͱ࿅͖ͬͯ·͢ • LayoutInspectModifier୯ମͷΞϓϩʔν͸ѱ͘ͳͦ͞͏ • Swift

    Playgroundsͷ༻్͚ͩͰͳ͘ɺΞϓϦέʔγϣϯ։ൃͷσόοΨ ͱͯ͠ൃల͍ͤͨ͞ • ྫ͑͹ɺShake GestureΛरͬͯɺදࣔ/ඇදࣔΛ੾Γସ͑Δ౳
  59. Reference • https://yutailang0119.hatenablog.com/entry/swiftui-with-swift-playgrounds • https://www.apple.com/swift/playgrounds/ • https://developer.apple.com/documentation/swift_playgrounds • https://developer.apple.com/xcode/swiftui/ •

    https://tech.d-itlab.co.jp/programming/1052/ • https://developer.apple.com/documentation/swiftui/viewmodifier • https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-custom-modifiers
  60. &OKPZ4XJGU1MBZHSPVOET 5IBOLT w NVUBZVUBSP!HNBJMDPN w IUUQTUXJUUFSDPNZVUBJMBOH w IUUQTHJUIVCDPNZVUBJMBOH