Upgrade to Pro — share decks privately, control downloads, hide ads and more …

マルチウィンドウ実践ガイド

Avatar for tatsubee tatsubee
October 05, 2025
93

 マルチウィンドウ実践ガイド

Avatar for tatsubee

tatsubee

October 05, 2025
Tweet

Transcript

  1. iPadOS 26͔ΒͷϚϧν΢Οϯυ΢֓ཁ iPadOS 26 ~ • Ϣʔβʔͷબ୒ʹΑͬͯϑϧεΫϦʔϯɺ΋͘͠͸΢Οϯυ΢෼ ׂͷͲͪΒ͔ͷݟͨ໨Ͱදࣔ͞ΕΔ • ΢Οϯυ΢෼ׂදࣔͷαΠζ͸ॊೈʹมಈͤ͞Δ͜ͱ͕Ͱ͖ɺҐ

    ஔ΋ࣗ༝ʹ഑ஔ͢Δ͜ͱ͕Ͱ͖Δ • (ࠓ·Ͱͱಉ͘͡)ΞϓϦͷ΢Οϯυ΢͸ෳ਺։͘͜ͱ͕Ͱ͖Δ • ΢Οϯυ΢ͷຕ਺͸ࠓ·ͰҎ্  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  2. iPadOS 26͔ΒͷϚϧν΢Οϯυ΢֓ཁ iPadOS 26 ~ • Ϣʔβʔͷબ୒ʹΑͬͯϑϧεΫϦʔϯɺ΋͘͠͸΢Οϯυ΢෼ ׂͷͲͪΒ͔ͷݟͨ໨Ͱදࣔ͞ΕΔ • ΢Οϯυ΢෼ׂදࣔͷαΠζ͸ॊೈʹมಈͤ͞Δ͜ͱ͕Ͱ͖ɺҐ

    ஔ΋ࣗ༝ʹ഑ஔ͢Δ͜ͱ͕Ͱ͖Δ • (ࠓ·Ͱͱಉ͘͡)ΞϓϦͷ΢Οϯυ΢͸ෳ਺։͘͜ͱ͕Ͱ͖Δ • ΢Οϯυ΢ͷຕ਺͸ࠓ·ͰҎ্  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  3. iPadOS 26͔ΒͷϚϧν΢Οϯυ΢֓ཁ iPadOS 26 ~ • Ϣʔβʔͷબ୒ʹΑͬͯϑϧεΫϦʔϯɺ΋͘͠͸΢Οϯυ΢෼ ׂͷͲͪΒ͔ͷݟͨ໨Ͱදࣔ͞ΕΔ • ΢Οϯυ΢෼ׂදࣔͷαΠζ͸ॊೈʹมಈͤ͞Δ͜ͱ͕Ͱ͖ɺҐ

    ஔ΋ࣗ༝ʹ഑ஔ͢Δ͜ͱ͕Ͱ͖Δ • (ࠓ·Ͱͱಉ͘͡)ΞϓϦͷ΢Οϯυ΢͸ෳ਺։͘͜ͱ͕Ͱ͖Δ • ΢Οϯυ΢ͷຕ਺͸ࠓ·ͰҎ্  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF J1BE04ʹ഑৴͍ͯ͠Δ͢΂ͯͷΞϓϦ͕ దԠ͢΂͖ཁ఺
  4. iPadOS 26͔ΒͷϚϧν΢Οϯυ΢֓ཁ iPadOS 26 ~ • Ϣʔβʔͷબ୒ʹΑͬͯϑϧεΫϦʔϯɺ΋͘͠͸΢Οϯυ΢෼ ׂͷͲͪΒ͔ͷݟͨ໨Ͱදࣔ͞ΕΔ • ΢Οϯυ΢෼ׂදࣔͷαΠζ͸ॊೈʹมಈͤ͞Δ͜ͱ͕Ͱ͖ɺҐ

    ஔ΋ࣗ༝ʹ഑ஔ͢Δ͜ͱ͕Ͱ͖Δ • (ࠓ·Ͱͱಉ͘͡)ΞϓϦͷ΢Οϯυ΢͸ෳ਺։͘͜ͱ͕Ͱ͖Δ • ΢Οϯυ΢ͷຕ਺͸ࠓ·ͰҎ্  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF J1BE04ʹ഑৴͍ͯ͠ΔΞϓϦ͕ରԠͰ͖Δͱ ʮڧΈʯͱͳΔମݧ
  5. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ toolbarΛ࢖༻͍ͯ͠Δ৔߹: Text(" ↖︎ ࠨ্ʹ஫໨") .toolbar { ToolbarItem(placement: .topBarLeading) {

    Text("1") } ToolbarItem(placement: .topBarLeading) { Text("2") } ToolbarItem(placement: .topBarLeading) { Text("3") } ToolbarItem(placement: .topBarTrailing) { Image(systemName: "ellipsis") }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  6. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ toolbarΛ࢖༻͍ͯ͠Δ৔߹: Text(" ↖︎ ࠨ্ʹ஫໨") .toolbar { ToolbarItem(placement: .topBarLeading) {

    Text("1") } ToolbarItem(placement: .topBarLeading) { Text("2") } ToolbarItem(placement: .topBarLeading) { Text("3") } ToolbarItem(placement: .topBarTrailing) { Image(systemName: "ellipsis") }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  7. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  8. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  9. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF ΢Οϯυ΢ίϯτϩʔϧͷ Ґஔ͕औಘͰ͖ͨ🎉
  10. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  11. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  12. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height + proxy.safeAreaInsets.top ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  13. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ ΢Οϯυ΢ίϯτϩʔϧͷҐஔΛऔಘ͢Δํ๏ GeometryReader { proxy in Rectangle() .fill(.red) .frame( width:

    proxy.containerCornerInsets.topLeading.width, height: proxy.containerCornerInsets.topLeading.height + proxy.safeAreaInsets.top ) .ignoresSafeArea() }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  14. ΢Οϯυ΢ίϯτϩʔϧΛߟྀ͢Δ UIKitͷ৔߹ @available(iOS 26.0, tvOS 26.0, *) @MainActor @preconcurrency public

    func layoutGuide( for region: UIView.LayoutRegion ) -> UILayoutGuide  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  15. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. OpenWindowAction @main struct iPadMultiWindowApp: App { var

    body: some Scene { WindowGroup { ContentView() } WindowGroup(id: "ID") { SomeView() } } }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  16. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. OpenWindowAction struct ContentView: View { @Environment(\.openWindow) var

    openWindow var body: some View { Button("৽͍͠΢Οϯυ΢Λ։͘") { openWindow(id: "ID") } } }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  17. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. SwiftUI struct ContentView: View { @Environment(\.openWindow) var

    openWindow var body: some View { Button("৽͍͠΢Οϯυ΢Λ։͘") { openWindow(id: "ID") } } }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  18. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. Drag & Drop struct ContentView: View {

    var body: some View { Image(resource) } }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  19. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. Drag & Drop struct ContentView: View {

    var body: some View { Image(resource) .onDrag { } } }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  20. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. Drag & Drop struct ContentView: View {

    var body: some View { Image(resource) .onDrag { let userActivity = NSUserActivity( activityType: "dev.shoryu.MultiWindowExample.openWindow" ) userActivity.targetContentIdentifier = "targetContentIdentifier" return NSItemProvider(object: userActivity) } } }  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF
  21. ৽͍͠΢Οϯυ΢Λ։͘ ৽͍͠΢Οϯυ΢ͷ։͖ํ ver. Drag & Drop WindowGroup(id: Self.activityType) { TargetView()

    } .handlesExternalEvents(matching: ["targetContentIdentifier"])  Ϛϧν΢Οϯυ΢࣮ફΨΠυʛUBUTVCFF