iOSDC Japan 2023 2023年9月1日
ϞʔμϧͷભҠΛཧղ͢Δ:VLJ:BTPTIJNB!ZBTP@TBO
View Slide
͡Ίʹw ͕͍࣌ؒͷͰɺओʹ4XJGU6*ʹߜͬͯ͠·͢w ಛʹݴٴ͍ͯ͠ͳ͚ΕɺJ04J1BE04ͷγϛϡϨʔλͰಈ࡞֬ೝͨ͠ڍಈΛͱʹ͍ͯ͠·͢
͢͜ͱw Ϟʔμϧʹ͍ͭͯw Ϟʔμϧͷw ϞʔμϧͷΛղܾ͢Δ
͜ͷτʔΫͰ͏༻ޠ
Ϟʔμϧw ͜ͷτʔΫͰJ04ͷը໘શମͷ্ʹ෴ͬͯผͷը໘Λલ໘ʹදࣔ͢ΔػೳΛද͢w 4IFFU"MFSUͳͲͷ͜ͱw ࣙॻతͳҙຯؾʹ͠ͳ͍
σʔλιʔεw !4UBUF0CTFSWBCMF0CKFDUɺ͞Βʹͦͷઌʹ͋Δ7JFXΛදࣔ͢ΔͨΊͷσʔλw ͜ͷτʔΫͰɺ7JFXͱσʔλιʔε͘Β͍ͷϨΠϠʔ͚Ͱ͢
Ϟʔμϧʹ͍ͭͯ
Ϟʔμϧͷछྨw 4IFFUw 'VMM4DSFFO$PWFSw "MFSUw 1PQPWFSw $POfiSNBUJPO%JBMPHʢ"DUJPO4IFFUʣw .FOV1JDLFS
Ϟʔμϧͷ֊w Ϟʔμϧʹ֊͕͋Δw 4IFFUɾ'VMM4DSFFO$PWFSɾ1PQPWFSෳ֊ੵΈॏͶΒΕΔ
ϧʔτͷ6*֊5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU8JOEPXϞʔμϧͷ֊4IFFUͷ߹
Ϟʔμϧୈ֊5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU ։͘8JOEPXϞʔμϧͷ֊4IFFUͷ߹ϧʔτͷ6*֊5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU
Ϟʔμϧୈ֊5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU8JOEPX5BC/BWJHBUJPO7JFX5FYU*NBHF-JTUϞʔμϧͷ֊4IFFUͷ߹❌։͚ͳ͍ϧʔτͷ6*֊
Ϟʔμϧୈ֊Ϟʔμϧୈ֊5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU։͘8JOEPX5BC/BWJHBUJPO7JFX5FYU*NBHF-JTUϞʔμϧͷ֊4IFFUͷ߹ϧʔτͷ6*֊
5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU8JOEPXϞʔμϧͷ֊4IFFUͷ߹ด͡Δϧʔτͷ6*֊
5BC/BWJHBUJPO7JFX5FYU*NBHF-JTU8JOEPXϞʔμϧͷ֊4IFFUͷ߹❌ ด͡Εͳ͍ϧʔτͷ6*֊
Ϟʔμϧͷରw 1PQPWFSɾ$POfiSNBUJPO%JBMPHͳͲࢦࣔ͢͠ઌͷ7JFX͕ඞཁw 4IFFUɾ'VMM4DSFFO$PWFSɾ"MFSUͳͲը໘શମ͔Βग़Δʢಉ͡֊Ͱ͋ΕNPEJfiFSΛ͚Δ7JFXͲ͜ʹͯ͠ಈ࡞ʹҧ͍ͳ͍ʣ
ϞʔμϧͷભҠͷίʔυJT1SFTFOUFEstruct ContentView: View {@State var isPresented: Bool = falsevar body: some View {Button(“Show") {isPresented = true}.sheet(isPresented: $isPresented) {...}}}όΠϯυͨ͠Λมߋ͢ΔͱભҠ#PPMͷΛόΠϯυ͢Δ
ϞʔμϧͷભҠͷίʔυJUFNstruct ContentView: View {@State var item: Item? = nilvar body: some View {Button("Show Sheet") {item = .foo}.sheet(item: $item) {...}}}όΠϯυͨ͠Ληοτ͢ΔͱભҠҙͷ0QUJPOBMͷΛόΠϯυ͢Δ
։͘ ด͡Δด͡ऴΘΔભҠͷ࣌ؒ࣠ͷྲྀΕભҠͷঢ়ଶJT1SFTFOUFEGBMTF։͖ऴΘΔJT1SFTFOUFEUSVF
։͘ ด͡Δด͡ऴΘ͔ͬͯΒग़Δ ͔ϞʔμϧදࣔதͷભҠભҠͷঢ়ଶଞͷϞʔμϧग़ͤͳ͍
खಈͰด͡Δw ϞʔμϧͷछྨʹΑͬͯɺεϫΠϓϘλϯλοϓͳͲͰด͡ΒΕΔw 4IFFUˠεϫΠϓw "MFSUͳͲˠϘλϯλοϓw 1PQPWFSͳͲˠ֎ଆΛλοϓ
.FOVw બࢶͷ6*1PQPWFSతͳϞʔμϧͷҰछw JT1SFTFOUFEͳͲͳ͘ɺϢʔβʔૢ࡞ͰͷΈભҠ͢Δ
։͖ํ ด͡ํ ্ͷ֊ දࣔઌͷ7JFX4IFFU όΠϯυόΠϯυεϫΠϓ։͚Δ ͍Βͳ͍'VMM4DSFFO$PWFS όΠϯυ όΠϯυ ։͚Δ ͍Βͳ͍1PQPWFS όΠϯυόΠϯυ֎Λλοϓ։͚Δ ͍Δ"MFSU όΠϯυόΠϯυϘλϯબ։͚ͳ͍ ͍Βͳ͍$POfiSNBUJPO%JBMPHόΠϯυόΠϯυϘλϯબ։͚ͳ͍ ͍Δ.FOV λοϓϘλϯબ֎Λλοϓ։͚ͳ͍ Ϟʔμϧͷछྨ
ϞʔμϧͰΓͨ͘ͳΔ͜ͱw %FFQ-JOLඇಉظॲཧͷྃ࣌ͳͲɺϢʔβʔૢ࡞Ҏ֎ͷλΠϛϯάͰϞʔμϧͷભҠΛ͍ͨ͠w ϞʔμϧͷσʔλιʔεΛมߋͨ͠Βɺͦͷঢ়ଶ͕ͦͷ··6*ʹө͞ΕΔΑ͏ʹ͍ͨ͠w ͦΕΒΛ࣮ݱ͠Α͏ͱ͢Δͱɺ৭ʑ͕ى͖Δ
Ϟʔμϧͷ
var body: some View {Button("Show") {isFirstPresented = trueisSecondPresented = trueisThirdPresented = true}.sheet(isPresented: $isFirstPresented) {Text("1").sheet(isPresented: $isSecondPresented) {Text("2").sheet(isPresented: $isThirdPresented) {Text("3")}...֊Ҏ্ಉ࣌ʹ։͚ͳ͍❌ͭ։͔ͳ͍
J04Ҏલෳ֊ಉ࣌ʹด͡Εͳ͍var body: some View {Button("Show") {...}.sheet(isPresented: $isFirstPresented) {Text("1").sheet(isPresented: $isSecondPresented) {Button("Close") {isFirstPresented = false}...J040,❌J04શ෦ด͡ͳ͍
var body: some View {....sheet(isPresented: $isSheetPresented) {Button("Switch to FullScreen") {isSheetPresented = falseisFullPresented = true}}.fullScreenCover(isPresented: $isFullPresented) {Text("Full Screen")}}ϞʔμϧͷΓସ͑'VMM4DSFFO͕4IFFUͰදࣔ͞ΕΔ❌4IFFUͰදࣔ͞ΕΔ
var body: some View {....sheet(isPresented: $isSheetPresented) {Button("Show Alert") {isSheetPresented = falseisAlertPresented = true}}.alert("Alert",isPresented: $isAlertPresented) {...}}ϞʔμϧͷΓସ͑"MFSU͕දࣔ͞Εͳ͍❌දࣔ͞Εͳ͍
ϞʔμϧͷΓସ͑1PQPWFSܥw ਧ͖ग़͠ͷ֎ଆԼͷ֊ͷ7JFXʹλοϓ͕௨Δw 1PQPWFSΛ։͍ͨ··ɺ4IFFUΛλοϓͯ͠։͜͏ͱͯ͠։͚ͳ͍w σʔλιʔεͱ7JFXͷ߹ੑ͕औΕͳ͘ͳΔͱͱ։͚ͳ͘ͳΔ❌λοϓͰ͖Δ͕4IFFUදࣔ͞Εͳ͍
var body: some View {Button("Freeze") {isFirstPresented = trueisSecondPresented = trueTask {try await Task.sleep(for: .milliseconds(100))isFirstPresented = false}}.sheet(isPresented: $isFirstPresented) {....sheet(isPresented: $isSecondPresented) {...}ભҠதʹด͡Α͏ͱ͢ΔͱϑϦʔζ❌ϑϦʔζ͢Δ
var body: some View {Button("Crash") {item = .oneTask {try await Task.sleep(for: .milliseconds(100))item = .twotry await Task.sleep(for: .milliseconds(100))item = .three}}.sheet(item: $item, content: { item in...})}ϞʔμϧΓସ͑தʹ͞ΒʹΓସ͑ΔͱΫϥογϡ❌Ϋϥογϡ͢Δ
ϞʔμϧͷΛղܾ͢Δ
ํw σʔλιʔεͰϞʔμϧͷঢ়ଶΛηοτͨ͠Βɺͦͷ··6*ʹө͞ΕΔΑ͏ʹ͍ͨ͠w J04Ҏ߱Λରʹͯ͠ด͡Δ࣌ͷΛճආw ϞʔμϧͷભҠதʹผͷભҠ͕ߦΘΕͳ͍Α͏ʹͯ͠Λճආw .FOVͷϞʔμϧ͕։͍͍ͯͯଞͷϞʔμϧ͕։͚ΔΑ͏ʹ͢Δ
enum Modal {case sheet(Item)case alert(...)...}σʔλιʔε.PEBM7JFX1PQPWFSOJM"MFSUOJM4IFFUOJMϞʔμϧͷঢ়ଶΛͭͷͰද͢ม1PQPWFSOJMOJM
enum Modal {case sheet(Item)case alert(...)...}σʔλιʔε.PEBMTIFFU GPP7JFX1PQPWFSOJM"MFSUOJM4IFFUGPPϞʔμϧͷঢ়ଶΛͭͷͰද͢ม1PQPWFSOJM
enum Modal {case sheet(Item)case alert(...)...}σʔλιʔε.PEBMBMFSU CBS7JFX1PQPWFSOJM"MFSUCBS4IFFUOJMϞʔμϧͷঢ়ଶΛͭͷͰද͢ม1PQPWFSOJM
σʔλιʔεͷөΛΒͤΔ։͘ ด͡Δ ։͘ݩσʔλόΠϯυ͢ΔσʔλCBSભҠͷঢ়ଶOJMOJMGPPGPPCBSOJM
σʔλιʔεͷөΛΒͤΔ։͘ ด͡Δ ։͘ݩσʔλόΠϯυ͢ΔσʔλGPP CBSOJMGPPOJM IPHભҠͷঢ়ଶIPHOJM
։͘ ด͡Δ ։͘ݩσʔλόΠϯυ͢ΔσʔλGPPOJMOJM CBSσʔλιʔεͷөΛΒͤΔભҠͷঢ়ଶOJMCBSGPP
.FOVΛͳΜͱ͔͢Δw JT1SFTFOUFEͳ͍͕ɺͷ7JFX͔Β.FOVΛফ͢͜ͱͰਧ͖ग़͠ΛඇදࣔʹͰ͖Δw ϞʔμϧΛදࣔ͢Δલʹ.FOVΛೖΕସ͑ͯด͓ͯ͘͡struct MenuView: View {...var body: some View {if flag {Menu(...)} else {Menu(...)}}}
.FOVΛดͨ͡ޙͷભҠw .FOVΛೖΕସ͑ͨͷͱಉ࣌ʹผͷϞʔμϧΛදࣔ͠Α͏ͱͯ͠ɺදࣔ͞Εͳ͍͜ͱ͕͋Δw .FOVΛด͔ͯ͡ΒϞʔμϧͷભҠΛ։࢝͢Δ·Ͱʹগؒ͠Λ։͚Δ
7JFXͷߋ৽4XJGU6*ͷ7JFXͷߋ৽αΠΫϧ7JFX͕ߋ৽͞ΕΔλΠϛϯά
σʔλιʔεͷมߋσʔλιʔεͷมߋσʔλιʔεͷมߋ4XJGU6*ͷ7JFXͷߋ৽αΠΫϧ7JFXͷߋ৽ఆظతʹ·ͱΊͯσʔλΛऔಘͯ͠ɺ͕ࠩ͋Ε7JFX͕ߋ৽͞ΕΔ
.FOVඇදࣔޙͷϞʔμϧөλΠϛϯά❌ ⭕7JFXͷߋ৽.FOVΛด͡Δ࣮ࡍʹ.FOV͕ด͡ΒΕΔผͷϞʔμϧͷ࣮ࡍͷදࣔ։࢝
ભҠͷλΠϛϯάऔಘ4IFFU'VMM4DSFFO$PWFS1PQPWFS։͘ ด͡ΔભҠͷঢ়ଶ7JFX$POUSPMMFSͷWJFX%JE"QQFBSϞʔμϧͷPO%JTBQQFBS
ભҠͷλΠϛϯάऔಘ։͘ ด͡ΔભҠͷঢ়ଶ"MFSU$POfiSNBUJPO%JBMPHPO"QQFBS PO%JTBQQFBSඵ͘Β͍
ભҠͷλΠϛϯάऔಘ։͘ ด͡ΔભҠͷঢ়ଶ"MFSU$POfiSNBUJPO%JBMPHPO"QQFBS PO%JTBQQFBSϘλϯλοϓ͞ΕͨΒڧ੍తʹดͨ͜͡ͱʹ͢Δඵ͘Β͍
·ͱΊϞʔμϧͷw Ϟʔμϧ͕։͚ͳ͍ͱͱ։͚ͳ͘ͳΔw σʔλιʔεΛมߋ͢ΔλΠϛϯάʹΑͬͯΫϥογϡϑϦʔζ͕ى͖Δw J04ҎલͰෳ֊ͷϞʔμϧΛಉ࣌ʹด͡Εͳ͍w .FOVʹભҠͷঢ়ଶΛཧ͢Δ"1*͕ͳ͍
·ͱΊϞʔμϧͷͷղܾw J04Ҏ߱ʹݶఆ͢Δʢด͡Δͷָ͕ʣw ಉ͡֊ͷϞʔμϧͷσʔλιʔεΛͭʹ·ͱΊΔw ϞʔμϧભҠதผͷભҠΛ͡Ίͳ͍w .FOVͷ7JFX͔ΒೖΕସ͑ͯด͡ɺ࣍ͷϞʔμϧͷભҠ։࢝ΛΒͤΔ
αϯϓϧίʔυϞʔμϧͷͷ࠶ݱIUUQTHJUIVCDPNPCKFDUJWFBVEJP.PEBM1SPCMFNϞʔμϧͷΛղܾͨ͠ྫIUUQTHJUIVCDPNPCKFDUJWFBVEJP.PEBM"SDIJUFDUVSF