$30 off During Our Annual Pro Sale. View Details »

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

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

kumamotone

August 07, 2019
Tweet

More Decks by kumamotone

Other Decks in Programming

Transcript

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

    View Slide

  2. • iOS/AndroidΤϯδχΞ
    • Yahoo!ΧϨϯμʔ iOS։ൃ
    • ษڧձӡӦ
    • Bonfire iOSɺWWDC Extended ͳͲ
    • ϚΠϒʔϜ
    • ఱؾͷࢠ
    ۽ຊ ࿨ਖ਼ (@kumamo_tone)

    View Slide

  3. • ࠓ೔͸ SwiftUI ͷίʔυΛಡΈॻ͖͢Δ্Ͱ

    ஌͓ͬͯ͘ͱྑ͍Swift 5.1ͷ৽ػೳʹ͍ͭͯ
    • Implicit return from single expressions
    • Function Builder
    • Opaque Result Type
    • ૝ఆର৅ऀ
    • ؾܰʹཧղ͍ͨ͠
    • SwiftUI ؾʹͳͬͯ͸͍Δ͚Ͳ͋·ΓखΛ෇͚Ε͍ͯͳ͍
    TL;DR

    View Slide

  4. View Slide

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

    View Slide

  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ϓϩτίϧͷఆٛ

    View Slide

  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ϓϩτίϧͷఆٛ
    ٙ໰

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  12. "
    Magic?

    View Slide

  13. "
    No.

    View Slide

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

    View Slide

  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ͷ৽ػೳ
    ͻͱͭΊʂ

    View Slide

  16. Implicit return from single expressions

    View Slide

  17. SE-0255: Implicit return from single expressions
    • ϝϦοτ
    • ͖ͬ͢Γ͢Δ
    ΫϩʔδϟͰ͸લ͔Βɺ͕ࣜͻͱ͔ͭ͠ͳ͍ͱ͖returnΛলུͰ͖ͨ
    let names = persons.map { $0.name }

    View Slide

  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 }

    View Slide

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

    View Slide

  20. struct ContentView: View {
    var body: some View {
    return VStack {
    Text(item.title)
    Text(item.subtitle)
    .foregroundColor(Color.gray)
    }
    }
    }
    SFUVSO͕লུ͞Ε͍ͯͨ

    View Slide

  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ͷ৽ػೳ
    ;ͨͭΊʂ

    View Slide

  22. Function builders (draft proposal)

    View Slide

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

    View Slide

  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)
    }
    ίϯύΠϥ͕ม׵

    View Slide

  25. struct ContentView: View {
    var body: some View {
    VStack {
    Text(item.title)
    Text(item.subtitle)
    .foregroundColor(Color.gray)
    }
    }
    }
    ఆٛΛݟΔ

    View Slide

  26. public struct VStack : View where
    Content : View {
    @inlinable public init(

    alignment: HorizontalAlignment = .center,
    spacing: CGFloat? = nil,
    @ViewBuilder content: () -> Content)
    public typealias Body = Never
    }
    ఆٛΛݟΔ

    View Slide

  27. @_functionBuilder public struct ViewBuilder {
    public static func buildBlock
    (_ content: Content)
    -> Content where Content : View
    }
    Ҿ਺1ݸͰɺͦΕͱಉ͡ܕͷViewΛฦ͍ͯ͠Δ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. extension ViewBuilder {
    public static func buildBlockC4, 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ݸ൛·Ͱ͋Δ

    View Slide

  33. extension ViewBuilder {
    public static func buildBlockC4, 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Λ࢖͏͜ͱ

    View Slide

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

    View Slide

  35. struct ContentView: View {
    var body: some View {
    return VStack {
    return ViewBuilder.buildBlock(
    Text(item.title),
    Text(item.subtitle)
    .foregroundColor(Color.gray)
    }
    }
    }
    }
    ͜͏ղऍ͞ΕΔ

    View Slide

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

    View Slide

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

    View Slide

  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
    }
    ࣗ෼Ͱͭ͘Δ͜ͱ΋Ͱ͖Δ

    View Slide

  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ͷ৽ػೳ
    ͍͞͝ʂ

    View Slide

  40. Opaque Result Type

    View Slide

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

    ʮ۩ମతͳܕ͸ެ։͠ͳ͍͚ͲɺViewϓϩτίϧʹద߹ͨ͠ԿΒ͔ͷܕʯ

    Ͱ͋Δ͜ͱΛද͢
    SE-0244: Opaque Result Type

    View Slide

  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ͱͯ͠ৼΔ෣͏

    View Slide

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

    View Slide

  44. struct ContentView: View {
    var body: VStack> {
    return VStack (
    return ViewBuilder.buildBlock(
    Text(item.title),
    Text(item.subtitle)
    .foregroundColor(Color.gray)
    )
    }
    }
    }
    ۩ମܕΛࢦఆͯ͠΋0,
    ͜ͷܗͳΒɺ΋͸΍4XJGUະຬͷจ๏Ͱ΋ҙຯ͕௨Δ

    View Slide

  45. ϝϦοτ
    • ͖ͬ͢Γ͢Δ
    SE-0244: Opaque Result Type

    View Slide

  46. ϝϦοτ
    • ͖ͬ͢Γ͢Δ
    SE-0244: Opaque Result Type
    VStack>
    ͦΕ͚ͩͰ͸ͳ͍
    ʢ˞Computed property ͸ܕએݴΛলུͰ͖ͳ͍ʣ

    View Slide

  47. • ίϯύΠϧ࣌ʹԿΒ͔ͷܕͰ͋Δ͜ͱ͕֬ఆ͢Δ
    • ίϯύΠϧ࣌ʹ෼͔ΔͷͰɺ࣮ߦ࣌ʹύϑΥʔϚϯεϩε͕ͳ͍
    SE-0244: Opaque Result Type

    View Slide

  48. SE-0244: Opaque Result Type
    func map(l: List, _ f: A -> B) -> List {
    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

    View Slide

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

    View Slide

  50. struct ContentView: View {
    var body: AnyView {
    AnyView(VStack {
    Text(item.title)
    Text(item.subtitle)
    .foregroundColor(Color.gray)
    })
    }
    }
    ܕফڈ͸Ͱ͖Δ͕ɺ
    ύϑΥʔϚϯεϩε͕͋Δ

    View Slide

  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ͷ৽ػೳ

    View Slide

  52. ·ͱΊ

    View Slide

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

    View Slide

  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

    View Slide

  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͸
    ࣜͭͳΒলུՄೳ

    View Slide

  56. View Slide

  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
    ·ͱΊ

    View Slide

  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

    View Slide

  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

    View Slide

  60. Enjoy SwiftUI!

    View Slide