Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

• Yutaro Muta @yutailang0119 • Hatena Co., Ltd. @Kyoto • Conference Staff • builderscon 2020 • try! Swift Tokyo 2020 • and more Who am I ?

Slide 3

Slide 3 text

Goal • iPadͰίʔσΟϯά͢ΔΑ͏ʹͳΔ • ͍࣋ͬͯͳ͍ਓ͸iPadΛങͬͯؼΔ • SwiftUIͷViewʹ͍ͭͯɺͪΐͬͱ஌Δ

Slide 4

Slide 4 text

What's Swift Playgrounds?

Slide 5

Slide 5 text

What's Swift Playgrounds? • iPadΞϓϦ Swift Playground • Document: https://developer.apple.com/documentation/swift_playgrounds • ϝΠϯϢʔε͸ɺϓϩάϥϛϯάڭҭΒ͍͠

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Run SwiftUI on Swift Playgrounds

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Run SwiftUI on Swift Playgrounds

Slide 10

Slide 10 text

Run Swift Playgrounds file on Xcode

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Run Swift Playgrounds file on Xcode

Slide 13

Slide 13 text

Pros/Cons of Swift Playgrounds

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

͓͠·͍

Slide 17

Slide 17 text

⚡͔͜͜Βຊฤ⚡

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

yutailang0119/LayoutInspector ໊લ͸෇͚͍ͯΔ͚Ͳɺ·ͩͰ͖ͯͳ͍

Slide 24

Slide 24 text

LayoutInspector

Slide 25

Slide 25 text

LayoutInspector import SwiftUI struct LayoutInspector: 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) } }

Slide 26

Slide 26 text

LayoutInspector

Slide 27

Slide 27 text

׬ᘳ

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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(_:) ͱ૊Έ߹Θͤͯ࢖͏

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Extension SwiftUI.View import SwiftUI extension SwiftUI.View { func labelPrimary() -> some View { self .modifier(PrimaryLabel()) } }

Slide 32

Slide 32 text

Custom ViewModifier

Slide 33

Slide 33 text

ͳΔ΄ͲɺΑͦ͞͏ͩ

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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) } }

Slide 37

Slide 37 text

LayoutInspectModifier (α)

Slide 38

Slide 38 text

_ViewModifier_Content LayoutInspectModifier (α)

Slide 39

Slide 39 text

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.

Slide 40

Slide 40 text

ViewModifierͷ࣮૷ • ViewModifier.Content ͸ɺݩͷViewͦͷ΋ͷͰ͸ͳ͘ɺProxy • contentʹ type(of:) Λ͔͚ͯ΋ɺݩͷViewͷType͸Θ͔Βͳ͍

Slide 41

Slide 41 text

OMG

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

LayoutInspecterΛมߋ

Slide 44

Slide 44 text

LayoutInspecter import SwiftUI struct LayoutInspector: 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)) } }

Slide 45

Slide 45 text

LayoutInspectModifier

Slide 46

Slide 46 text

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) } }

Slide 47

Slide 47 text

TypeNameLayoutInspectModifier

Slide 48

Slide 48 text

TypeNameLayoutInspectModifier import SwiftUI struct TypeNameLayoutInspectModifier: 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) } }

Slide 49

Slide 49 text

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)) } }

Slide 50

Slide 50 text

࣮ߦʂ

Slide 51

Slide 51 text

࣮ߦʂ

Slide 52

Slide 52 text

Αͦ͞͏

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

contentView.frame()

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

ࠓ೔͸͜͜·Ͱ

Slide 57

Slide 57 text

·ͱΊ

Slide 58

Slide 58 text

·ͱΊ • iPad͚ͩͰ΋ɺSwiftɺSwiftUIΛॻ͘͜ͱ͸Ͱ͖Δ • yutailang0119/LayoutInspector ͸ɺ΋͏ͪΐͬͱ࿅͖ͬͯ·͢ • LayoutInspectModifier୯ମͷΞϓϩʔν͸ѱ͘ͳͦ͞͏ • Swift Playgroundsͷ༻్͚ͩͰͳ͘ɺΞϓϦέʔγϣϯ։ൃͷσόοΨ ͱͯ͠ൃల͍ͤͨ͞ • ྫ͑͹ɺShake GestureΛरͬͯɺදࣔ/ඇදࣔΛ੾Γସ͑Δ౳

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

&OKPZ4XJGU1MBZHSPVOET 5IBOLT w NVUBZVUBSP!HNBJMDPN w IUUQTUXJUUFSDPNZVUBJMBOH w IUUQTHJUIVCDPNZVUBJMBOH