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

モーダルの遷移を理解する

 モーダルの遷移を理解する

iOSDC Japan 2023
2023年9月1日

Yuki Yasoshima

August 29, 2023
Tweet

More Decks by Yuki Yasoshima

Other Decks in Programming

Transcript

  1. ϞʔμϧͷભҠΛཧղ͢Δ
    :VLJ:BTPTIJNB
    !ZBTP@TBO

    View Slide

  2. ͸͡Ίʹ
    w ͕࣌ؒ୹͍ͷͰɺओʹ4XJGU6*ʹߜͬͯ࿩͠·͢
    w ಛʹݴٴ͍ͯ͠ͳ͚Ε͹ɺJ04J1BE04ͷγϛϡϨʔλͰಈ࡞֬ೝͨ͠
    ڍಈΛ΋ͱʹ͍ͯ͠·͢

    View Slide

  3. ࿩͢͜ͱ
    w Ϟʔμϧʹ͍ͭͯ
    w Ϟʔμϧͷ໰୊఺
    w Ϟʔμϧͷ໰୊Λղܾ͢Δ

    View Slide

  4. ͜ͷτʔΫͰ࢖͏༻ޠ

    View Slide

  5. Ϟʔμϧ
    w ͜ͷτʔΫͰ͸J04ͷը໘શମͷ্ʹ෴ͬͯผͷը໘Λલ໘ʹදࣔ͢ΔػೳΛ
    ද͢
    w 4IFFU΍"MFSUͳͲͷ͜ͱ
    w ࣙॻతͳҙຯ͸ؾʹ͠ͳ͍

    View Slide

  6. σʔλιʔε
    w !4UBUF΍0CTFSWBCMF0CKFDU΍ɺ͞Βʹͦͷઌʹ͋Δ7JFXΛදࣔ͢ΔͨΊͷ
    σʔλ
    w ͜ͷτʔΫͰ͸ɺ7JFXͱσʔλιʔε͘Β͍ͷϨΠϠʔ෼͚Ͱ࿩͢

    View Slide

  7. Ϟʔμϧʹ͍ͭͯ

    View Slide

  8. Ϟʔμϧͷछྨ
    w 4IFFU
    w 'VMM4DSFFO$PWFS
    w "MFSU
    w 1PQPWFS
    w $PO
    fi
    SNBUJPO%JBMPHʢ"DUJPO4IFFUʣ
    w .FOV1JDLFS

    View Slide

  9. Ϟʔμϧͷ֊૚
    w Ϟʔμϧʹ͸֊૚͕͋Δ
    w 4IFFUɾ'VMM4DSFFO$PWFSɾ1PQPWFS͸ෳ਺֊૚ੵΈॏͶΒΕΔ

    View Slide

  10. ϧʔτͷ6*֊૚
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    8JOEPX
    Ϟʔμϧͷ֊૚
    4IFFUͷ৔߹

    View Slide

  11. Ϟʔμϧୈ֊૚
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU ։͘
    8JOEPX
    Ϟʔμϧͷ֊૚
    4IFFUͷ৔߹
    ϧʔτͷ6*֊૚
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU

    View Slide

  12. Ϟʔμϧୈ֊૚
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    8JOEPX
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    Ϟʔμϧͷ֊૚
    4IFFUͷ৔߹
    ❌։͚ͳ͍
    ϧʔτͷ6*֊૚

    View Slide

  13. Ϟʔμϧୈ֊૚
    Ϟʔμϧୈ֊૚
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    ։͘
    8JOEPX
    5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    Ϟʔμϧͷ֊૚
    4IFFUͷ৔߹
    ϧʔτͷ6*֊૚

    View Slide

  14. 5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    8JOEPX
    Ϟʔμϧͷ֊૚
    4IFFUͷ৔߹
    ด͡Δ
    ϧʔτͷ6*֊૚

    View Slide

  15. 5BC
    /BWJHBUJPO
    7JFX
    5FYU
    *NBHF
    -JTU
    8JOEPX
    Ϟʔμϧͷ֊૚
    4IFFUͷ৔߹
    ❌ ด͡Εͳ͍
    ϧʔτͷ6*֊૚

    View Slide

  16. Ϟʔμϧͷର৅
    w 1PQPWFSɾ$PO
    fi
    SNBUJPO%JBMPHͳͲ͸
    ࢦࣔ͢͠ઌͷ7JFX͕ඞཁ
    w 4IFFUɾ'VMM4DSFFO$PWFSɾ"MFSUͳͲ
    ͸ը໘શମ͔Βग़Δʢಉ͡֊૚Ͱ͋Ε͹
    NPEJ
    fi
    FSΛ෇͚Δ7JFX͸Ͳ͜ʹͯ͠΋ಈ
    ࡞ʹҧ͍͸ͳ͍ʣ

    View Slide

  17. ϞʔμϧͷભҠͷίʔυ
    JT1SFTFOUFE
    struct ContentView: View {


    @State var isPresented: Bool = false




    var body: some View {


    Button(“Show") {


    isPresented = true


    }


    .sheet(isPresented: $isPresented) {


    ...


    }


    }


    }
    όΠϯυͨ͠஋Λมߋ͢ΔͱભҠ
    #PPMͷ஋ΛόΠϯυ͢Δ

    View Slide

  18. ϞʔμϧͷભҠͷίʔυ
    JUFN
    struct ContentView: View {


    @State var item: Item? = nil




    var body: some View {


    Button("Show Sheet") {


    item = .foo


    }


    .sheet(item: $item) {


    ...


    }


    }


    }
    όΠϯυͨ͠஋Ληοτ͢ΔͱભҠ
    ೚ҙͷ0QUJPOBMͷ஋ΛόΠϯυ͢Δ

    View Slide

  19. ։͘ ด͡Δ
    ด͡ऴΘΔ
    ભҠͷ࣌ؒ࣠ͷྲྀΕ
    ભҠͷঢ়ଶ
    JT1SFTFOUFEGBMTF
    ։͖ऴΘΔ
    JT1SFTFOUFEUSVF

    View Slide

  20. ։͘ ด͡Δ
    ด͡ऴΘ͔ͬͯΒग़Δ ͔΋

    ϞʔμϧදࣔதͷભҠ
    ભҠͷঢ়ଶ
    ଞͷϞʔμϧ͸ग़ͤͳ͍

    View Slide

  21. खಈͰด͡Δ
    w ϞʔμϧͷछྨʹΑͬͯɺεϫΠϓ΍ϘλϯλοϓͳͲͰด͡ΒΕΔ
    w 4IFFUˠεϫΠϓ
    w "MFSUͳͲˠϘλϯλοϓ
    w 1PQPWFSͳͲˠ֎ଆΛλοϓ

    View Slide

  22. .FOV
    w બ୒ࢶͷ6*͸1PQPWFSతͳϞʔμϧͷ
    Ұछ
    w JT1SFTFOUFEͳͲ͸ͳ͘ɺϢʔβʔૢ
    ࡞ͰͷΈભҠ͢Δ

    View Slide

  23. ։͖ํ ด͡ํ ্ͷ֊૚ දࣔઌͷ7JFX
    4IFFU όΠϯυ
    όΠϯυ
    εϫΠϓ
    ։͚Δ ͍Βͳ͍
    'VMM4DSFFO$PWFS όΠϯυ όΠϯυ ։͚Δ ͍Βͳ͍
    1PQPWFS όΠϯυ
    όΠϯυ
    ֎Λλοϓ
    ։͚Δ ͍Δ
    "MFSU όΠϯυ
    όΠϯυ
    Ϙλϯબ୒
    ։͚ͳ͍ ͍Βͳ͍
    $PO
    fi
    SNBUJPO
    %JBMPH
    όΠϯυ
    όΠϯυ
    Ϙλϯબ୒
    ։͚ͳ͍ ͍Δ
    .FOV λοϓ
    Ϙλϯબ୒
    ֎Λλοϓ
    ։͚ͳ͍
    Ϟʔμϧͷछྨ

    View Slide

  24. ϞʔμϧͰ΍Γͨ͘ͳΔ͜ͱ
    w %FFQ-JOL΍ඇಉظॲཧͷ׬ྃ࣌ͳͲɺϢʔβʔૢ࡞Ҏ֎ͷλΠϛϯάͰϞ
    ʔμϧͷભҠΛ͍ͨ͠
    w ϞʔμϧͷσʔλιʔεΛมߋͨ͠Βɺͦͷঢ়ଶ͕ͦͷ··6*ʹ൓ө͞ΕΔΑ
    ͏ʹ͍ͨ͠
    w ͦΕΒΛ࣮ݱ͠Α͏ͱ͢Δͱɺ৭ʑ໰୊͕ى͖Δ

    View Slide

  25. Ϟʔμϧͷ໰୊఺

    View Slide

  26. var body: some View {


    Button("Show") {


    isFirstPresented = true


    isSecondPresented = true


    isThirdPresented = true


    }


    .sheet(isPresented: $isFirstPresented) {


    Text("1")


    .sheet(isPresented: $isSecondPresented) {


    Text("2")


    .sheet(isPresented: $isThirdPresented) {


    Text("3")


    }


    ...
    ֊૚Ҏ্ಉ࣌ʹ։͚ͳ͍
    ❌ͭ໨͸։͔ͳ͍

    View Slide

  27. J04Ҏલ͸ෳ਺֊૚ಉ࣌ʹด͡Εͳ͍
    var body: some View {


    Button("Show") {


    ...


    }


    .sheet(isPresented: $isFirstPresented) {


    Text("1")


    .sheet(isPresented: $isSecondPresented) {


    Button("Close") {


    isFirstPresented = false


    }


    ...
    J04͸0,
    ❌J04͸શ෦ด͡ͳ͍

    View Slide

  28. var body: some View {


    ...


    .sheet(isPresented: $isSheetPresented) {


    Button("Switch to FullScreen") {


    isSheetPresented = false


    isFullPresented = true


    }


    }


    .fullScreenCover(


    isPresented: $isFullPresented) {


    Text("Full Screen")


    }


    }
    Ϟʔμϧͷ੾Γସ͑
    'VMM4DSFFO͕4IFFUͰදࣔ͞ΕΔ
    ❌4IFFUͰදࣔ͞ΕΔ

    View Slide

  29. var body: some View {


    ...


    .sheet(isPresented: $isSheetPresented) {


    Button("Show Alert") {


    isSheetPresented = false


    isAlertPresented = true


    }


    }


    .alert("Alert",


    isPresented: $isAlertPresented) {


    ...


    }


    }
    Ϟʔμϧͷ੾Γସ͑
    "MFSU͕දࣔ͞Εͳ͍
    ❌දࣔ͞Εͳ͍

    View Slide

  30. Ϟʔμϧͷ੾Γସ͑
    1PQPWFSܥ
    w ਧ͖ग़͠ͷ֎ଆ͸Լͷ֊૚ͷ7JFXʹ΋
    λοϓ͕௨Δ
    w 1PQPWFSΛ։͍ͨ··ɺ4IFFUΛλοϓ
    ͯ͠։͜͏ͱͯ͠΋։͚ͳ͍
    w σʔλιʔεͱ7JFXͷ੔߹ੑ͕औΕͳ
    ͘ͳΔͱ౓ͱ։͚ͳ͘ͳΔ
    ❌λοϓͰ͖Δ͕
    4IFFU͸දࣔ͞Εͳ͍

    View Slide

  31. var body: some View {


    Button("Freeze") {


    isFirstPresented = true


    isSecondPresented = true


    Task {


    try await Task.sleep(for: .milliseconds(100))


    isFirstPresented = false


    }


    }


    .sheet(isPresented: $isFirstPresented) {


    ...


    .sheet(isPresented: $isSecondPresented) {


    ...


    }




    ભҠதʹด͡Α͏ͱ͢ΔͱϑϦʔζ
    ❌ϑϦʔζ͢Δ

    View Slide

  32. var body: some View {


    Button("Crash") {


    item = .one


    Task {


    try await Task.sleep(for: .milliseconds(100))


    item = .two


    try await Task.sleep(for: .milliseconds(100))


    item = .three


    }


    }


    .sheet(item: $item, content: { item in


    ...


    })


    }
    Ϟʔμϧ੾Γସ͑தʹ͞Βʹ੾Γସ͑ΔͱΫϥογϡ
    ❌Ϋϥογϡ͢Δ

    View Slide

  33. Ϟʔμϧͷ໰୊Λղܾ͢Δ

    View Slide

  34. ํ਑
    w σʔλιʔεͰϞʔμϧͷঢ়ଶΛηοτͨ͠Βɺͦͷ··6*ʹ൓ө͞ΕΔΑ͏
    ʹ͍ͨ͠
    w J04Ҏ߱Λର৅ʹͯ͠ด͡Δ࣌ͷ໰୊Λճආ
    w ϞʔμϧͷભҠதʹผͷભҠ͕ߦΘΕͳ͍Α͏ʹͯ͠໰୊Λճආ
    w .FOVͷϞʔμϧ͕։͍͍ͯͯ΋ଞͷϞʔμϧ͕։͚ΔΑ͏ʹ͢Δ

    View Slide

  35. enum Modal {


    case sheet(Item)


    case alert(...)


    ...


    }
    σʔλιʔε
    .PEBM
    7JFX
    1PQPWFS
    OJM
    "MFSU
    OJM
    4IFFU
    OJM
    Ϟʔμϧͷঢ়ଶΛͭͷ஋Ͱද͢
    ม׵
    1PQPWFS
    OJM
    OJM

    View Slide

  36. enum Modal {


    case sheet(Item)


    case alert(...)


    ...


    }
    σʔλιʔε
    .PEBM
    TIFFU GPP

    7JFX
    1PQPWFS
    OJM
    "MFSU
    OJM
    4IFFU
    GPP
    Ϟʔμϧͷঢ়ଶΛͭͷ஋Ͱද͢
    ม׵
    1PQPWFS
    OJM

    View Slide

  37. enum Modal {


    case sheet(Item)


    case alert(...)


    ...


    }
    σʔλιʔε
    .PEBM
    BMFSU CBS

    7JFX
    1PQPWFS
    OJM
    "MFSU
    CBS
    4IFFU
    OJM
    Ϟʔμϧͷঢ়ଶΛͭͷ஋Ͱද͢
    ม׵
    1PQPWFS
    OJM

    View Slide

  38. σʔλιʔεͷ൓өΛ஗ΒͤΔ
    ։͘ ด͡Δ ։͘
    ݩσʔλ
    όΠϯυ͢Δσʔλ
    CBS
    ભҠͷঢ়ଶ
    OJM
    OJM
    GPP
    GPP
    CBS
    OJM

    View Slide

  39. σʔλιʔεͷ൓өΛ஗ΒͤΔ
    ։͘ ด͡Δ ։͘
    ݩσʔλ
    όΠϯυ͢Δσʔλ
    GPP CBS
    OJM
    GPP
    OJM IPH
    ભҠͷঢ়ଶ
    IPH
    OJM

    View Slide

  40. ։͘ ด͡Δ ։͘
    ݩσʔλ
    όΠϯυ͢Δσʔλ
    GPP
    OJM
    OJM CBS
    σʔλιʔεͷ൓өΛ஗ΒͤΔ
    ભҠͷঢ়ଶ
    OJM
    CBS
    GPP

    View Slide

  41. .FOVΛͳΜͱ͔͢Δ
    w JT1SFTFOUFE͸ͳ͍͕ɺ਌ͷ7JFX͔Β
    .FOVΛফ͢͜ͱͰਧ͖ग़͠Λඇදࣔʹ
    Ͱ͖Δ
    w ϞʔμϧΛදࣔ͢Δલʹ.FOVΛೖΕସ
    ͑ͯด͓ͯ͘͡
    struct MenuView: View {


    ...




    var body: some View {


    if flag {


    Menu(...)


    } else {


    Menu(...)


    }


    }


    }

    View Slide

  42. .FOVΛดͨ͡ޙͷભҠ
    w .FOVΛೖΕସ͑ͨͷͱಉ࣌ʹผͷϞʔμϧΛදࣔ͠Α͏ͱͯ͠΋ɺදࣔ͞
    Εͳ͍͜ͱ͕͋Δ
    w .FOVΛด͔ͯ͡ΒϞʔμϧͷભҠΛ։࢝͢Δ·Ͱʹগؒ͠Λ։͚Δ

    View Slide

  43. 7JFXͷߋ৽
    4XJGU6*ͷ7JFXͷߋ৽αΠΫϧ
    7JFX͕ߋ৽͞ΕΔλΠϛϯά

    View Slide

  44. σʔλιʔεͷมߋ
    σʔλιʔεͷมߋ
    σʔλιʔεͷมߋ
    4XJGU6*ͷ7JFXͷߋ৽αΠΫϧ
    7JFXͷߋ৽
    ఆظతʹ·ͱΊͯσʔλΛ
    औಘͯ͠ɺࠩ෼͕͋Ε͹
    7JFX͕ߋ৽͞ΕΔ

    View Slide

  45. .FOVඇදࣔޙͷϞʔμϧ൓өλΠϛϯά
    ❌ ⭕
    7JFXͷߋ৽
    .FOVΛด͡Δ
    ࣮ࡍʹ.FOV͕ด͡ΒΕΔ
    ผͷϞʔμϧͷ
    ࣮ࡍͷදࣔ։࢝

    View Slide

  46. ભҠͷλΠϛϯάऔಘ
    4IFFU'VMM4DSFFO$PWFS1PQPWFS
    ։͘ ด͡Δ
    ભҠͷঢ়ଶ
    7JFX$POUSPMMFSͷ
    WJFX%JE"QQFBS
    Ϟʔμϧ಺ͷ
    PO%JTBQQFBS

    View Slide

  47. ભҠͷλΠϛϯάऔಘ
    ։͘ ด͡Δ
    ભҠͷঢ়ଶ
    "MFSU$PO
    fi
    SNBUJPO%JBMPH
    PO"QQFBS PO%JTBQQFBS
    ඵ͘Β͍

    View Slide

  48. ભҠͷλΠϛϯάऔಘ
    ։͘ ด͡Δ
    ભҠͷঢ়ଶ
    "MFSU$PO
    fi
    SNBUJPO%JBMPH
    PO"QQFBS PO%JTBQQFBS
    Ϙλϯλοϓ͞ΕͨΒ
    ڧ੍తʹดͨ͜͡ͱʹ͢Δ
    ඵ͘Β͍

    View Slide

  49. ·ͱΊ
    Ϟʔμϧͷ໰୊
    w Ϟʔμϧ͕։͚ͳ͍ͱ౓ͱ։͚ͳ͘ͳΔ
    w σʔλιʔεΛมߋ͢ΔλΠϛϯάʹΑͬͯΫϥογϡ΍ϑϦʔζ͕ى͖Δ
    w J04ҎલͰ͸ෳ਺֊૚ͷϞʔμϧΛಉ࣌ʹด͡Εͳ͍
    w .FOVʹ͸ભҠͷঢ়ଶΛ؅ཧ͢Δ"1*͕ͳ͍

    View Slide

  50. ·ͱΊ
    Ϟʔμϧͷ໰୊ͷղܾ
    w J04Ҏ߱ʹݶఆ͢Δʢด͡Δͷָ͕ʣ
    w ಉ͡֊૚ͷϞʔμϧͷσʔλιʔεΛͭʹ·ͱΊΔ
    w ϞʔμϧભҠத͸ผͷભҠΛ͸͡Ίͳ͍
    w .FOV͸਌ͷ7JFX͔ΒೖΕସ͑ͯด͡ɺ࣍ͷϞʔμϧͷભҠ։࢝Λ஗ΒͤΔ

    View Slide

  51. αϯϓϧίʔυ
    Ϟʔμϧͷ໰୊ͷ࠶ݱ
    IUUQTHJUIVCDPNPCKFDUJWFBVEJP.PEBM1SPCMFN
    Ϟʔμϧͷ໰୊Λղܾͨ͠ྫ
    IUUQTHJUIVCDPNPCKFDUJWFBVEJP.PEBM"SDIJUFDUVSF

    View Slide