SwiftUI を理解するために必要な Swift 5.1 の新機能 (some View編)

266af7918931b0ea15eae9e8f42ecfa6?s=47 kumamotone
August 07, 2019

SwiftUI を理解するために必要な Swift 5.1 の新機能 (some View編)

266af7918931b0ea15eae9e8f42ecfa6?s=128

kumamotone

August 07, 2019
Tweet

Transcript

  1. SwiftUI Λཧղ͢ΔͨΊʹඞཁͳ Swift 5.1 ͷ৽ػೳ (some Viewฤ) 2019/08/07 Bonfire iOS

    #6 twitter.com/kumamo_tone
  2. • iOS/AndroidΤϯδχΞ • Yahoo!ΧϨϯμʔ iOS։ൃ • ษڧձӡӦ • Bonfire iOSɺWWDC

    Extended ͳͲ • ϚΠϒʔϜ • ఱؾͷࢠ ۽ຊ ࿨ਖ਼ (@kumamo_tone)
  3. • ࠓ೔͸ SwiftUI ͷίʔυΛಡΈॻ͖͢Δ্Ͱ
 ஌͓ͬͯ͘ͱྑ͍Swift 5.1ͷ৽ػೳʹ͍ͭͯ • Implicit return from

    single expressions • Function Builder • Opaque Result Type • ૝ఆର৅ऀ • ؾܰʹཧղ͍ͨ͠ • SwiftUI ؾʹͳͬͯ͸͍Δ͚Ͳ͋·ΓखΛ෇͚Ε͍ͯͳ͍ TL;DR
  4. None
  5. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } }
  6. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } public protocol View { associatedtype Body : View var body: Self.Body { get } } 7JFXϓϩτίϧͷ͜ͱ 7JFXϓϩτίϧͷఆٛ
  7. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } public protocol View { associatedtype Body : View var body: Self.Body { get } } 7JFXϓϩτίϧͷ͜ͱ 7JFXϓϩτίϧͷఆٛ ٙ໰
  8. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } TPNFͬͯԿʁ͆
  9. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } TPNFͬͯԿʁ͆ ͜ͷதͰ͸ Կ͕ߦΘΕ͍ͯΔʁ
  10. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } SFUVSOͲ͜ʹߦͬͨʁ ͜ͷதͰ͸ Կ͕ߦΘΕ͍ͯΔʁ TPNFͬͯԿʁ͆
  11. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } SFUVSOͲ͜ʹߦͬͨʁ ʁ TPNFͬͯԿʁ͆ ͜ͷதͰ͸ Կ͕ߦΘΕ͍ͯΔʁ
  12. " Magic?

  13. " No.

  14. Swift5.1ʹ௥Ճ͞Εͨɺ3ͭͷ৽ػೳʹΑͬͯઆ໌Ͱ͖Δ • Implicit return from single expressions • Function builders

    • Opaque Result Type Swift5.1ͷ৽ػೳ
  15. Swift5.1ʹ௥Ճ͞Εͨɺ3ͭͷ৽ػೳʹΑͬͯઆ໌Ͱ͖Δ • Swift Evolution: SE-0255 • Implicit return from single

    expressions • Swift Evolution: SE-XXXX • Function builders • Swift Evolution: SE-0244 • Opaque Result Type Swift5.1ͷ৽ػೳ ͻͱͭΊʂ
  16. Implicit return from single expressions

  17. SE-0255: Implicit return from single expressions • ϝϦοτ • ͖ͬ͢Γ͢Δ

    ΫϩʔδϟͰ͸લ͔Βɺ͕ࣜͻͱ͔ͭ͠ͳ͍ͱ͖returnΛলུͰ͖ͨ let names = persons.map { $0.name }
  18. SE-0255: Implicit return from single expressions struct Rectangle { var

    width = 0.0, height = 0.0 var area: Double { width * height } } ؔ਺΍ Computed Property Ͱ΋OK ΫϩʔδϟͰ͸લ͔Βɺ͕ࣜͻͱ͔ͭ͠ͳ͍ͱ͖returnΛলུͰ͖ͨ • ϝϦοτ • ͖ͬ͢Γ͢Δ let names = persons.map { $0.name }
  19. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } }
  20. struct ContentView: View { var body: some View { return

    VStack { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } SFUVSO͕লུ͞Ε͍ͯͨ
  21. • Swift Evolution: SE-0255 • Implicit return from single expressions

    • Swift Evolution: SE-XXXX • Function builders (draft proposal) • Swift Evolution: SE-0244 • Opaque Result Type Swift5.1ͷ৽ػೳ ;ͨͭΊʂ
  22. Function builders (draft proposal)

  23. • վߦ۠੾Γͷཁૉ͔ͨͪΒɺม਺એݴͱؔ਺ݺͼग़͠Λੜ੒͢Δ • @_functionBuilderΛ͚ͭͨؔ਺͸ɺFunction builderʹͳΔ SE-XXXX: Function Builders

  24. • վߦ۠੾Γͷཁૉ͔ͨͪΒɺม਺એݴͱؔ਺ݺͼग़͠Λੜ੒͢Δ • @_functionBuilderΛ͚ͭͨstruct͸ɺFunction builderʹͳΔ SE-XXXX: Function Builders // @TupleBuilder͸

    // @_functionBuilderͱͯ͠Ͳ͔͜Ͱఆٛ @TupleBuilder func build() -> (Int, Int, Int) { 1 2 3 } func build() -> (Int, Int, Int) { let _a = 1 let _b = 2 let _c = 3 return TupleBuilder .buildBlock(_a, _b, _c) } ίϯύΠϥ͕ม׵
  25. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } ఆٛΛݟΔ
  26. public struct VStack<Content> : View where Content : View {

    @inlinable public init(
 alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content) public typealias Body = Never } ఆٛΛݟΔ
  27. @_functionBuilder public struct ViewBuilder { public static func buildBlock<Content> (_

    content: Content) -> Content where Content : View } Ҿ਺1ݸͰɺͦΕͱಉ͡ܕͷViewΛฦ͍ͯ͠Δ
  28. extension ViewBuilder { public static func buildBlock<C0, C1> (_ c0:

    C0, _ c1: C1) -> TupleView<(C0, C1)> where C0 : View, C1 : View } Ҿ਺2ݸͰɺͦΕͱಉ͡ܕͷTupleView<(C0, C1)>Λฦ͍ͯ͠Δ
  29. extension ViewBuilder { public static func buildBlock<C0, C1> (_ c0:

    C0, _ c1: C1) -> TupleView<(C0, C1)> where C0 : View, C1 : View } Ҿ਺2ݸͰɺͦΕͱಉ͡ܕͷTupleView<(C0, C1)>Λฦ͍ͯ͠Δ ʹ74UBDLͷҾ਺ͷਖ਼ମ
  30. extension ViewBuilder { public static func buildBlock<C0, C1, C2>(_ c0:

    C0, _ c1: C1, _ c2: C2) -> TupleView<(C0, C1, C2)> where C0 : View, C1 : View, C2 : View } 3ݸ൛
  31. extension ViewBuilder { public static func buildBlock<C0, C1, C2, C3>(_

    c0: C0, _ c1: C1, _ c2: C2, _ c3: C3) -> TupleView<(C0, C1, C2, C3)> where C0 : View, C1 : View, C2 : View, C3 : View } 4ݸ൛…
  32. extension ViewBuilder { public static func buildBlock<C0, C1, C2, C3,

    C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View } 10ݸ൛·Ͱ͋Δ
  33. extension ViewBuilder { public static func buildBlock<C0, C1, C2, C3,

    C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View } 10ݸ൛·Ͱ͋Δ ʹ10ݸ൛·Ͱ͔͠ͳ͍ ͦΕҎ্ฒ΂͍ͨͱ͖͸ɺ GroupΛ࢖͏͜ͱ
  34. struct ContentView: View { var body: some View { return

    VStack { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } ͭ·Γ͜ͷϒϩοΫ͸
  35. struct ContentView: View { var body: some View { return

    VStack { return ViewBuilder.buildBlock( Text(item.title), Text(item.subtitle) .foregroundColor(Color.gray) } } } } ͜͏ղऍ͞ΕΔ
  36. ฦΓ஋ͷܕ͸ $5FYU $5FYUͳͷͰɺ 5VQMF7JFX 5FYU 5FYU ʹͳΔ struct ContentView: View

    { var body: some View { return VStack { return ViewBuilder.buildBlock( Text(item.title), Text(item.subtitle) .foregroundColor(Color.gray) } } } }
  37. ฦΓ஋ͷܕ͸ɺ74UBDLͷܕύϥϝʔλ$POUFOUʹΑͬͯ 74UBDL5VQMF7JFX 5FYU 5FYU ʹͳΔ struct ContentView: View { var

    body: some View { return VStack { return ViewBuilder.buildBlock( Text(item.title), Text(item.subtitle) .foregroundColor(Color.gray) } } } }
  38. @_functionBuilder public struct NumsBuilder { public static func buildBlock(_ nums:

    Int...) -> [Int] { nums } } func printNums(@NumsBuilder numsBuilder: () -> [Int]) { numsBuilder().forEach { print($0) } } printNums { 1 2 3 } ࣗ෼Ͱͭ͘Δ͜ͱ΋Ͱ͖Δ
  39. • Swift Evolution: SE-0255 • Implicit return from single expressions

    • Swift Evolution: SE-XXXX • Function builders (draft proposal) • Swift Evolution: SE-0244 • Opaque Result Type Swift5.1ͷ৽ػೳ ͍͞͝ʂ
  40. Opaque Result Type

  41. • δΣωϦΫεͷΑ͏ͳ΋ͷ • some Protocol ͷΑ͏ͳܕ͕ Opaque Result Type •

    some View ͸
 ʮ۩ମతͳܕ͸ެ։͠ͳ͍͚ͲɺViewϓϩτίϧʹద߹ͨ͠ԿΒ͔ͷܕʯ
 Ͱ͋Δ͜ͱΛද͢ SE-0244: Opaque Result Type
  42. struct ContentView: View { var body: some View { return

    VStack { return ViewBuilder.buildBlock( Text(item.title), Text(item.subtitle) .foregroundColor(Color.gray) ) } } } 74UBDL5VQMF7JFX 5FYU 5FYU  ͷ࣮ࡍͷܕ͸ɺ ͨͱ͑͹ɺTPNF7JFX ͕ͩɺ֎ଆ͔Βݟͨͱ͖͸7JFXͱͯ͠ৼΔ෣͏
  43. struct ContentView: View { var body: VStack<TupleView<(Text, Text)>> { return

    VStack ( return ViewBuilder.buildBlock( Text(item.title), Text(item.subtitle) .foregroundColor(Color.gray) ) } } } ۩ମܕΛࢦఆͯ͠΋0,
  44. struct ContentView: View { var body: VStack<TupleView<(Text, Text)>> { return

    VStack ( return ViewBuilder.buildBlock( Text(item.title), Text(item.subtitle) .foregroundColor(Color.gray) ) } } } ۩ମܕΛࢦఆͯ͠΋0, ͜ͷܗͳΒɺ΋͸΍4XJGUະຬͷจ๏Ͱ΋ҙຯ͕௨Δ
  45. ϝϦοτ • ͖ͬ͢Γ͢Δ SE-0244: Opaque Result Type

  46. ϝϦοτ • ͖ͬ͢Γ͢Δ SE-0244: Opaque Result Type VStack<TupleView<(Text, Text)>> ͦΕ͚ͩͰ͸ͳ͍

    ʢ˞Computed property ͸ܕએݴΛলུͰ͖ͳ͍ʣ
  47. • ίϯύΠϧ࣌ʹԿΒ͔ͷܕͰ͋Δ͜ͱ͕֬ఆ͢Δ • ίϯύΠϧ࣌ʹ෼͔ΔͷͰɺ࣮ߦ࣌ʹύϑΥʔϚϯεϩε͕ͳ͍ SE-0244: Opaque Result Type

  48. SE-0244: Opaque Result Type func map<A, B>(l: List<A>, _ f:

    A -> B) -> List<B> { switch l { case .Nil: return .Nil case let .Cons(x, xs): return cons(f(x), map(xs, f)) } } [1,2].map { $0 * 2 } δΣωϦΫεͷܕ͸
 ֎ଆ͔Β࣮ࡍͷܕΛ
 ࢦఆͯ֬͠ఆ͢Δ Opaque Result Type Ͱ͸
 ಺ଆ͔Β࣮ࡍͷܕ͕֬ఆ͢Δ *OU*OU struct ContentView: View { var body: some View { VStack { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } 74UBDL 5VQMF7JFX 5FYU 5FYU 
  49. struct ContentView: View { var body: View { VStack {

    Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } 7JFX͸QSPUPDPMͰɺ BTTPDJBUFEUZQFΛ΋ͭͷͰɺ ͜͏͸ॻ͚ͳ͍
  50. struct ContentView: View { var body: AnyView { AnyView(VStack {

    Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) }) } } ܕফڈ͸Ͱ͖Δ͕ɺ ύϑΥʔϚϯεϩε͕͋Δ
  51. • Swift Evolution: SE-0255 • Implicit return from single expressions

    • Swift Evolution: SE-XXXX • Function builders (draft proposal) • Swift Evolution: SE-0244 • Opaque Result Type Swift5.1ͷ৽ػೳ
  52. ·ͱΊ

  53. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } SFUVSO͸ ࣜͭͳΒলུՄೳ
  54. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } SFUVSO͸ ࣜͭͳΒলུՄೳ 'VODUJPO#VJMEFSʹΑͬͯɺ 7JFX#VJMEFSCVJME#MPDL 5FYU 5FYU ͱղऍ͞ΕΔ ࣮ࡍͷܕ͸ɺ74UBDL5VQMF7JFX 5FYU 5FYU 
  55. struct ContentView: View { var body: some View { VStack

    { Text(item.title) Text(item.subtitle) .foregroundColor(Color.gray) } } } TPNF7JFX͸ 7JFXʹద߹͢Δ ԿΒ͔ͷܕͰ͋Δ͜ͱΛࣔ͢ 'VODUJPO#VJMEFSʹΑͬͯɺ 7JFX#VJMEFSCVJME#MPDL 5FYU 5FYU ͱղऍ͞ΕΔ ࣮ࡍͷܕ͸ɺ74UBDL5VQMF7JFX 5FYU 5FYU  SFUVSO͸ ࣜͭͳΒলུՄೳ
  56. None
  57. SwiftUI ͸Swift5.1ͷػೳʹΑ͖ͬͯͬ͢Γॻ͚ΔΑ͏ʹͳ͍ͬͯΔ • Swift Evolution: SE-0255 • Implicit return from

    single expressions • Swift Evolution: SE-XXXX • Function builders • Swift Evolution: SE-0244 • Opaque Result Type ·ͱΊ
  58. • Swift Evolution • https://github.com/apple/swift-evolution/blob/master/proposals/0255-omit-return.md • https://github.com/apple/swift-evolution/blob/9992cf3c11c2d5e0ea20bee98657d93902d5b174/proposals/XXXX- function-builders.md • https://github.com/apple/swift-evolution/blob/master/proposals/0244-opaque-result-types.md

    References
  59. • SwiftUIͷຐ๏Λ࣮ݱ͢Δ࢓૊Έ (Custom Attributes, Function Builder) • https://qiita.com/kentrino/items/dc6e77a0ddd21187cc55 • SwiftUIͷίʔυΛಡΈղ͘

    • https://blog.personal-factory.com/2019/06/07/understand-swiftui-code/ • Swift 5.1 ʹಋೖ͞ΕΔ Opaque Result Type ͱ͸Կ͔ • https://qiita.com/koher/items/338d2f2d0c4731e3508f • Opaque Result Typeͷղઆ • https://qiita.com/omochimetaru/items/f13fe3e54fab01648ba4 See Also
  60. Enjoy SwiftUI!