Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
詳解UIWindow
Search
Atsuya Sato
August 23, 2024
Programming
5.7k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
詳解UIWindow
2024/08/22(木)~24(土)に開催されたiOSDC Japan 2024で発表した2024/08/23 15:40〜 Track A「詳解UIWindow」の資料です
Atsuya Sato
August 23, 2024
More Decks by Atsuya Sato
See All by Atsuya Sato
アプリ内にテーマ機能を実装する / pixiv-app-talk-202604-theme-feature
natmark
0
76
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
700
iOS 17で追加されたSubscriptionStoreView を利用して5分でサブスク実装チャレンジ
natmark
0
1.6k
Pastelaのアプリ内課金開発の裏側 / pixiv-app-night-202502-pastela-iap
natmark
2
230
画面最前面に表示されるデバッグツールを作る
natmark
2
360
最低サポートOSバージョンをあげた時のストア表示について / potatotips81-store-page-apperance-with-deployment-target-updated
natmark
2
820
施策基盤としてのディープリンク〜なめらかにアプリが開く体験のために〜
natmark
9
9.2k
チームでSwiftUIを書くために / After Party iOSDC Japan 2021 SwiftUI
natmark
3
1.2k
iOSDC_SwiftUI_Text
natmark
4
6k
Other Decks in Programming
See All in Programming
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
240
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
4.7k
気持ちぃ〜角丸 Squircle
ryu1013
0
340
Seven New Principles of Software Engineering
yegor256
0
330
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
120
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
190
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
210
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
370
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.7k
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
240
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
1
200
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
Featured
See All Featured
Faster Mobile Websites
deanohume
310
32k
Side Projects
sachag
456
43k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
Music & Morning Musume
bryan
48
7.5k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
380
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
380
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
490
HDC tutorial
michielstock
2
980
Statistics for Hackers
jakevdp
799
230k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Transcript
ৄղUIWindow iOSDC Japan 2024 2024/08/23(ۚ) 15:40-16:00 Track A 1 pixiv
Inc. atsuyan
2 atsuyan / ͋ͭ (𝕏: @n_atmark) ϐΫγϒגࣜձࣾ ৽نࣄۀ෦ iOSΤϯδχΞ 20242݄த్ೖࣾ
iPad͚ϖΠϯτπʔϧPastelaͷ։ൃΛ୲ ϘϧμϦϯά͕झຯͰ͢!
3
ΞδΣϯμ • UIWindowͲ͏͍͏Ϋϥεͳͷ͔ • UIWindowͷදࣔํ๏ͱಛੑʹ͍ͭͯ • SwiftUIͰͷUIWindowऔಘʹ͍ͭͯ • ·ͱΊ 4
UIWindowͲ͏͍͏Ϋϥεͳͷ͔ 5
6 UIWindow | Apple Developer Documentation - https://developer.apple.com/documentation/uikit/uiwindow
UIWindowͷׂ 7 ΞϓϦͷίϯςϯπΛදࣔ͢ΔͨΊͷΟϯυͷఏڙ
UIWindowͷׂ • දࣔ͢ΔrootViewControllerͷཧ • ࠲ඪͷม • ΩʔϘʔυΠϕϯτͷλʔήοτཧ • ΟϯυͷॏͳΓ(Z࣠Ϩϕϧ)ͷཧ 8
ΞϓϦͷίϯςϯπΛදࣔ͢ΔͨΊͷΟϯυͷఏڙ
UIWindowͷׂ • දࣔ͢ΔrootViewControllerͷཧ 9 var rootViewController: UIViewController? { get set
}
UIWindowͷׂ • ࠲ඪͷม 10 func convert(_ point: CGPoint, to window:
UIWindow?) -> CGPoint func convert(_ point: CGPoint, from window: UIWindow?) -> CGPoint func convert(_ rect: CGRect, to window: UIWindow?) -> CGRect func convert(_ rect: CGRect, from window: UIWindow?) -> CGRect
UIWindowͷׂ • ΩʔϘʔυΠϕϯτͷλʔήοτཧ 11 var isKeyWindow: Bool { get }
var canBecomeKey: Bool { get } func makeKeyAndVisible() func makeKey() func becomeKey() func resignKey()
UIWindowͷׂ • ΟϯυͷॏͳΓ(Z࣠Ϩϕϧ)ͷཧ 12 var windowLevel: UIWindow.Level { get set
}
UIWindowͷؔ࿈Ϋϥε • ը໘αΠζΛऔಘ͍ͨ͠߹ʹݕ౼͞ΕΔΫϥε • UIScreen • UIWindowScene • UIWindow •
UIView 13
14 Introducing Multiple Windows on iPad | WWDC19 - https://developer.apple.com/videos/play/wwdc2019/212/
~ iOS 13.0
15 Introducing Multiple Windows on iPad | WWDC19 - https://developer.apple.com/videos/play/wwdc2019/212/
iOS 13.0+
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"Apple Studio Display Free Mockups" © BRIX Templates (Licensed under
CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
"Apple Studio Display Free Mockups" © BRIX Templates (Licensed under
CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
UIWindowͷؔ࿈Ϋϥε • UIScreen … ཧతͳσόΠεͷը໘αΠζ • UIWindowScene … γʔϯͷը໘αΠζ •
UIWindow … Οϯυͷը໘αΠζ • UIView … Viewͷը໘αΠζ 29
αΠζΛͲ͏औಘ͢Δ͔ • αΠζऔಘͷҙ 30 UIApplication.shared.keyWindow UIApplication.shared.windows UIScreen.screens UIScreen.main
αΠζΛͲ͏औಘ͢Δ͔ • αΠζऔಘͷҙ 31 @available(iOS, introduced: 2.0, deprecated: 13.0, message:ŋŋŋ)
UIApplication.shared.keyWindow @available(iOS, introduced: 2.0, deprecated: 15.0, message:ŋŋŋ) UIApplication.shared.windows @available(iOS, introduced: 3.2, deprecated: 16.0, message:ŋŋŋ) UIScreen.screens // soft-deprecated @available(iOS, introduced: 2.0, deprecated: 100000, message:ŋŋŋ) UIScreen.main
UIScreen.screens ͲͷΠϯελϯε ͕Ͳͬͪͩ…? iPadଆͷαΠζҰԠUIScreen.main ͰऔΕ͢Δ͕… (soft-deprecated) "Apple Studio Display Free
Mockups" © BRIX Templates (Licensed under CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
UIApplication.shared.connectedScenes ͲͷΠϯελϯε͕ Ͳͷγʔϯͩ…? "Apple Studio Display Free Mockups" © BRIX
Templates (Licensed under CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
UIApplication.shared.windows ͍ͬͺ͍͋Δͧ…? "Apple Studio Display Free Mockups" © BRIX Templates
(Licensed under CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
keyWindowͬͯͲΕͩ??? UIApplication.shared.keyWindow ? ? ? ? "Apple Studio Display Free
Mockups" © BRIX Templates (Licensed under CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
windowScene.windows ͲͷΠϯελϯε ͕Ͳͬͪͩ…? "Apple Studio Display Free Mockups" © BRIX
Templates (Licensed under CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
windowScene.keyWindow keyWindowͬͯͲΕͩ??? ? ? "Apple Studio Display Free Mockups" ©
BRIX Templates (Licensed under CC BY 4.0) "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
αΠζΛͲ͏औಘ͢Δ͔ • ྫ͑ • ֎෦σΟεϓϨΠଓ࣌ʹ͕ࣗࣗͲͷσόΠεͷεΫ Ϧʔϯͳͷ͔UIScreenͰ͔Βͳ͍ (αΠζͰஅ͢Δͱ ͍͏ख͋Δ͕…) • ಉ͡Α͏ʹSplitViewͷࠨଆͷUIWindowScene͕ͲΕͳͷ͔ɻ
Έ͍ͨͳࣄconnectedScenes͔Β͔Βͳ͍ 38
αΠζΛͲ͏औಘ͢Δ͔ 39 UIViewͷํ͔Βॱ൪ʹḷΔͷ͕ྑ͍
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
view.window @MainActor class UIView : UIResponder { var window: UIWindow?
{ get } } "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
@MainActor class UIWindow : UIView { weak var windowScene: UIWindowScene?
{ get set } } window.windowScene "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
@MainActor class UIWindowScene : UIScene { var screen: UIScreen {
get } } windowScene.screen "iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
αΠζΛͲ͏औಘ͢Δ͔ 44 UIViewͷํ͔Βॱ൪ʹḷΔͷ͕ྑ͍ • UIView͔Βॱ൪ʹḷΔ͜ͱͰରԠ͢Δ্ҐΫϥεΛऔಘͰ͖Δ • UIView 1 — 0…1
UIWindow • UIWindow 1 — 0..1 UIWindowScene • UIWindowScene 1 — 1 UIScreen (SwiftUIʹ͍ͭͯޙ΄Ͳ)
UIWindowͷදࣔํ๏ͱಛੑʹ͍ͭͯ 45
UIWindowͷ׆༻ • UIView (UIViewController) Ͱͳ͘ΟϯυͷϨΠϠʔͰॏͳ ΓΛཧͰ͖Δ • άϩʔόϧʹը໘࠷લ໘ʹཁૉΛදࣔ͢Δͷʹར༻Ͱ͖Δ • શը໘ϩʔσΟϯάͷදࣔ
• τʔετͷදࣔ • σόοάπʔϧͷදࣔͳͲ 46
47 UIWindowͷॏͳΓͰ ProgressΛ࣮ UIViewͷॏͳΓͰ ProgressΛ࣮ "iPhone mockups" © Clément Diouloufet
(Licensed under CC BY 4.0)
UIWindowͷ׆༻ • ཁૉΛॏͶΔ͚ͩͳΒUIViewͷaddSubViewͰ্ʹॏͶͨΓɺ SwiftUIͷ ZStack / overlay ͕͋Δ • ྫ͑
UIViewContoller Λpresentͨ͠ΓSwiftUIͰsheetΛදࣔ͠ ͨΓ͢Δͱɺը໘࠷લ໘Ͱͳ͘ͳͬͯ͠·͏ • ৗʹը໘࠷લ໘ʹද͍ࣔͨ࣌͠ʹUIWindow͕ศར 48
UIWindowͷදࣔ • UIWindowͷදࣔUIViewͷΑ͏ʹ addSubView(_:) ͢Δܗࣜͱ গ͠ҟͳΔ 49
UIWindowͷදࣔ 50 final class SceneDelegate: UIResponder, UIWindowSceneDelegate{ var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } // ᶃ Πϯελϯεͷੜ let window = UIWindow(windowScene: windowScene) // ᶄ rootViewControllerͷઃఆ window.rootViewController = CustomViewController() // ᶅ UIWindowͷදࣔ window.makeKeyAndVisible() // ᶆ Πϯελϯεͷอ࣋ self.window = window } }
makeKeyAndVisibleʹ͍ͭͯ 51
makeKeyAndVisibleʹ͍ͭͯ 52
makeKeyAndVisibleͷޡղ • makeKeyAndVisible() ɺUIWindowΛΩʔΟϯυ (isKeyWindow: true) ʹͯ͠UIWindowΛදࣔঢ়ଶʹ͢Δॲཧ • ΩʔΟϯυʹͳΔ͜ͱͰը໘࠷લ໘ʹදࣔ͞ΕΔͱࢥΘ ΕΔ͜ͱ͕͋Δ͕ɺؔͳ͍
53
UIWindowΛը໘࠷લ໘ʹදࣔ͢Δʹ • Z࣠ࢦఆ͢Δͷʹ windowLevel: UIWindow.Level ͕͋Δ • windowLevel ͷߴ͍ॱʹલ໘ͱͳ͍ͬͯΔ •
public init(_ rawValue: CGFloat) • UIWindow.Level (.normal / .alert / .statusBar) 54
UIWindowΛը໘࠷લ໘ʹදࣔ͢Δʹ • windowLevel ͕ಉ͡UIWindowؒͷલޙͲ͏ܾ·͍ͬͯΔʁ • isKeyWindow ͕ઌ಄Λอূ͢ΔͷͰͳ͍ • UIApplication.shared.windows ͷ߱ॱͰͳ͍
• windowScene.windows ͷ߱ॱͰͳ͍ 55
UIWindowΛը໘࠷લ໘ʹදࣔ͢Δʹ • windowLevel ͕ಉ͡UIWindowؒʹ͓͚Δදࣔॱ • ৽͘͠ visible ঢ়ଶʹͳͬͨUIWindow΄Ͳલʹදࣔ͞ΕΔ 56
UIWindowΛը໘࠷લ໘ʹදࣔ͢Δʹ • windowLevel ͕ಉ͡UIWindowؒʹ͓͚Δදࣔॱ • ৽͘͠ visible ঢ়ଶʹͳͬͨUIWindow΄Ͳલʹදࣔ͞ΕΔ 57 UIWindow
ͷ visibility ʹมߋ͕͋ͬͨࡍʹ UIWindow.didBecomeVisibleNotification Ͱߋ৽͞Εͨ UIWindow ͕௨͞ΕΔͷͰɺ͜Εͷ௨͕࠷ޙʹ͞Εͨͷ*1 *1: Undocumented ͕ͩɺprivate APIΛίʔϧͯ͠ௐͯΈͨײ͓ͦ͡Β࣮͘ࡍͷදࣔॱܾఆ UIScene ͕ ෦Ͱอ͍࣋ͯ͠Δ NSArray *_visibleWindows ॱʹͳ͍ͬͯͦ͏
ΩʔΟϯυͱ • UIWindowScene͝ͱʹҰ͚ͭͩଘࡏ͢Δ isKeyWindow ͷ͕ true ͱͳ͍ͬͯΔUIWindow • ΩʔೖྗΛड͚͚ΒΕΔUIWindow •
࠲ඪΛ࣋ͨͳ͍ΠϕϯτΛ௨͢ΔͨΊʹΘΕΔ 58
59 UIWindow1 UIWindow2 UIWindow3 "iPad Pro Mockup" © Eduard (Licensed
under CC BY 4.0)
60 UIWindow1 UIWindow2 UIWindow3 "iPad Pro Mockup" © Eduard (Licensed
under CC BY 4.0) "Mac Keyboard Mockup for Figma" © ͋͛ (Licensed under CC BY 4.0) ? ? ?
61 UIWindow1 UIWindow2 UIWindow3 "iPad Pro Mockup" © Eduard (Licensed
under CC BY 4.0) "Mac Keyboard Mockup for Figma" © ͋͛ (Licensed under CC BY 4.0) isKeyWindow: false isKeyWindow: false isKeyWindow: true isKeyWindow: true
ΩʔΟϯυͱ • ը໘ͷλοϓϚεϗόʔͳͲ࠲ඪΛ࣋ͭΠϕϯτ • λοϓҐஔʹଘࡏ͢ΔUIWindow͕ΠϕϯτΛड͚औΔ • ΩʔϘʔυೖྗͳͲͷ࠲ඪΛ࣋ͨͳ͍ΠϕϯτΩʔΟϯ υ͕ड͚औΔ ͨͩ͠ΩʔΟϯυҎ֎ͷUIWindow͕ʮ࠲ඪΛ࣋ͭΠϕϯ τʯड͚औΔͱΩʔΟϯυҠΓมΘΔͷͰҙ
62
ͦͷଞͷؾΛ͚ͭΔ͖UIWindowͷಛੑက • ྫ͑ϑϨʔϜͷڍಈ • UIWindowͷ frame.size ͕UIWindowSceneͷ coordinateSpace.bounds.size ͱಉ͡߹ •
ʮશը໘දࣔʯ͞Ε͍ͯΔͱΈͳ͞ΕΔ 63
"iPad Pro Mockup" © Eduard (Licensed under CC BY 4.0)
64
ͦͷଞͷؾΛ͚ͭΔ͖UIWindowͷಛੑက • ʮશը໘දࣔʯ͞Ε͍ͯΔ߹ • frame.origin ʹͲΜͳΛઃఆͯ͠ CGPoint.zero Ͱ্ॻ͖͞ Εͯ͠·͏ 65
ͦͷଞͷؾΛ͚ͭΔ͖UIWindowͷಛੑက • ྫ͑εςʔλεόʔͷڍಈ • εςʔλεόʔͷදࣔɾඇදࣔʮશը໘දࣔ͞Ε͍ͯΔʯ UIWindowͷ͏ͪʮ࠷લ໘දࣔʯ͞Ε͍ͯΔUIWindowʹඥͮ ͘rootViewControllerͷ prefersStatusBarHidden ʹӨڹΛड͚ Δ
66
ͦͷଞͷؾΛ͚ͭΔ͖UIWindowͷಛੑက 67 final class CustomViewController: UIViewController { private var isHidden:
Bool override var prefersStatusBarHidden: Bool { return isHidden } init(isHidden: Bool, color: UIColor?) { self.isHidden = isHidden super.init(nibName: nil, bundle: nil) view.backgroundColor = color } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
68 @main class AppDelegate: UIResponder, UIApplicationDelegate { var windows: [UIWindow]
= [] func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool { let blueWindow = UIWindow(frame: UIScreen.main.bounds) blueWindow.rootViewController = CustomViewController(isHidden: false, color: .blue) blueWindow.windowLevel = .init(2) blueWindow.isHidden = false windows.append(blueWindow) let redWindow = UIWindow(frame: UIScreen.main.bounds) // ΑΓલ໘ʹ࠷લ໘දࣔ͞ΕͨblueWindow͕͍ΔͷͰεςʔλεόʔӅΕͳ͍ redWindow.rootViewController = CustomViewController(isHidden: true, color: .red) redWindow.windowLevel = .init(1) redWindow.isHidden = false windows.append(redWindow) let greenWindow = UIWindow(frame: .init(x: 20, y: 20, width: 100, height: 100)) // ࠷લ໘ʹදࣔ͞Ε͍ͯΔ͕શը໘දࣔ͞Ε͍ͯͳ͍ͷͰεςʔλεόʔӅΕͳ͍ greenWindow.rootViewController = CustomViewController(isHidden: true, color: .green) greenWindow.windowLevel = .init(3) greenWindow.isHidden = false windows.append(greenWindow) return true } }
SwiftUIͰͷUIWindowදࣔʹ͍ͭͯ 69
SwiftUIͰUIWindowΛऔಘ͢Δ • 1: AppͷView͔Βऔಘ͢Δ߹ • 2: App֎Ͱ࡞ͨ͠UIWindowʹඥͮ͘SwiftUIͷView͔Βऔಘ͢ Δ߹ 70
AppͷView͔Βऔಘ͢Δ߹ • AppͷView͔ΒUIWindowΛऔಘ͍ͨ͠߹ObservableObject ͳSceneDelegateΛར༻͢Δͱྑ͍ 71
1: AppͷView͔Βऔಘ͢Δ߹ 72 @main struct SampleAppApp: App { // UIApplicationDelegateAdaptorΛར༻͢Δ
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } } final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role) if connectingSceneSession.role == .windowApplication { configuration.delegateClass = SceneDelegate.self } return configuration } }
1: AppͷView͔Βऔಘ͢Δ߹ 73 final class SceneDelegate: UIResponder, UIWindowSceneDelegate, ObservableObject {
var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } self.window = windowScene.keyWindow // γʔϯͷଓ࣌ʹkeyWindowΛͱͬͯͳ͍ (UIWindow͕Ұ͚ͭͩͳͷͰ) } }
1: AppͷView͔Βऔಘ͢Δ߹ 74 struct ContentView: View { @EnvironmentObject var sceneDelegate:
SceneDelegate var body: some View { // EnvironmentObject͔Βऔಘͨ͠sceneDelegateΛར༻ͯ͠ sceneDelegate.window͕ར༻Ͱ͖Δ } }
2: App֎Ͱ࡞ͨ͠UIWindowͷ߹ 75 extension UIWindow: ObservableObject {} final class SceneDelegate:
NSObject, UIWindowSceneDelegate{ var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } let window = UIWindow(windowScene: windowScene) // environmentObjectͰUIWindowΛͯ͋͛͠Δ window.rootViewController = UIHostingController(rootView: OverlayView().ignoresSafeArea().environmentObject(window)) window.isHidden = false self.window = window } }
2: App֎Ͱ࡞ͨ͠UIWindowͷ߹ 76 struct OverlayView: View { @EnvironmentObject var window:
UIWindow var body: some View { // EnvironmentObject͔Βऔಘͨ͠window͕ར༻Ͱ͖Δ } }
UIWindowSceneͷαΠζ͕มΘͬͨ͜ͱΛݕ͍ͨ͠ • windowScene ͷ delegate ϝιουʹ↓͕͋Δ windowScene(_:didUpdate:interfaceOrientation:traitCollection:) • ͜Ε͑ͦ͏ͳؾ͢Δ͕… 77
UIWindowSceneͷαΠζ͕มΘͬͨ͜ͱΛݕ͍ͨ͠ • windowScene(_:didUpdate:interfaceOrientation:traitCollection:) • UIApplicationDelegateAdaptorܦ༝ͷ߹͜ͷdelegateϝιο υݺΕͳ͍ • UISceneConfigurationͷdelegateClassʹઃఆͨ͠ SceneDelegate͕ͦͷ··ΘΕΔΘ͚Ͱͳ͘ɺ SwiftUI.AppSceneDelegate͕෦తʹར༻͞ΕΔͨΊ
78
UIWindowSceneͷαΠζ͕มΘͬͨ͜ͱΛݕ͍ͨ͠ • WindowGroup ͷԼʹ GeometryReader Λઃஔ͢Δ͔͠ͳ͍͔ … 79
·ͱΊ • UIWindowUIWindowSceneͷαΠζ͕ཉ͍͠߹ΑΓԼҐ ͷΫϥε͔Βٯॱʹḷ͍ͬͯ͘ͱྑ͍ • UIWindowͷදࣔॱܾఆUIViewͱҧ͍ͬͯΔͷͰҙ͕ඞ ཁɻεςʔλεόʔͷදࣔͷڍಈॱ൪͕Өڹ͢Δ • SwiftUI͔ΒUIWindowʹΞΫηε͍ͨ͠߹ UIApplicationDelegateAdaptorΛ࣮͢ΔͱEnvironmentObjectܦ
༝ͰऔಘͰ͖Δ 80