From 2a7f24b1bd1f1aaac9a13c13a404c9e36eecac8e Mon Sep 17 00:00:00 2001 From: Shuming Liu Date: Mon, 14 Sep 2026 17:48:42 +0800 Subject: [PATCH] ios full screen --- .../UserInterfaceState.xcuserstate | Bin 27278 -> 28233 bytes ios/OralTrainer/AppDelegate.swift | 34 ++++++++++++++++++ ios/OralTrainer/Resources/Info.plist | 2 ++ .../Views/FullscreenPlayerView.swift | 30 ++++++++++++---- ios/OralTrainer/Views/RootView.swift | 24 ++++--------- 5 files changed, 66 insertions(+), 24 deletions(-) diff --git a/ios/OralTrainer.xcodeproj/project.xcworkspace/xcuserdata/liushuming.xcuserdatad/UserInterfaceState.xcuserstate b/ios/OralTrainer.xcodeproj/project.xcworkspace/xcuserdata/liushuming.xcuserdatad/UserInterfaceState.xcuserstate index 0ce9aee8bf940b74296482ab90059ae3077a77ab..3b3d8e5c2605afee4d2b6ad9ab09aa67bbd12592 100644 GIT binary patch delta 13001 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 eD!;CLRQbH}h4 UIInterfaceOrientationMask { AppDelegate.orientationLock } + + static func lockOrientation(_ mask: UIInterfaceOrientationMask) { + orientationLock = mask + guard let scene = UIApplication.shared.connectedScenes + .compactMap({ $0 as? UIWindowScene }) + .first(where: { $0.activationState == .foregroundActive }) + ?? UIApplication.shared.connectedScenes.compactMap({ $0 as? UIWindowScene }).first + else { + return + } + + func update(_ controller: UIViewController?) { + guard let controller else { return } + controller.setNeedsUpdateOfSupportedInterfaceOrientations() + update(controller.presentedViewController) + controller.children.forEach { update($0) } + } + + let requested: UIInterfaceOrientationMask + if mask.contains(.landscapeRight) { + requested = .landscapeRight + } else if mask.contains(.landscapeLeft) { + requested = .landscapeLeft + } else { + requested = mask + } + + scene.windows.forEach { update($0.rootViewController) } + scene.requestGeometryUpdate(.iOS(interfaceOrientations: requested)) { _ in } + DispatchQueue.main.async { + scene.windows.forEach { update($0.rootViewController) } + scene.requestGeometryUpdate(.iOS(interfaceOrientations: requested)) { _ in } + } + } } diff --git a/ios/OralTrainer/Resources/Info.plist b/ios/OralTrainer/Resources/Info.plist index e67e3d5..1cb0a2f 100644 --- a/ios/OralTrainer/Resources/Info.plist +++ b/ios/OralTrainer/Resources/Info.plist @@ -33,6 +33,8 @@ 需要麦克风权限才能进行录音评测 UILaunchScreen + UIRequiresFullScreen + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait diff --git a/ios/OralTrainer/Views/FullscreenPlayerView.swift b/ios/OralTrainer/Views/FullscreenPlayerView.swift index 6ed296e..4ee8ff3 100644 --- a/ios/OralTrainer/Views/FullscreenPlayerView.swift +++ b/ios/OralTrainer/Views/FullscreenPlayerView.swift @@ -9,6 +9,29 @@ struct FullscreenPlayerView: View { @State private var explanationSentence: SentenceBoundary? var body: some View { + GeometryReader { proxy in + let fakeLandscape = proxy.size.height > proxy.size.width + playerChrome + .frame( + width: fakeLandscape ? proxy.size.height : proxy.size.width, + height: fakeLandscape ? proxy.size.width : proxy.size.height + ) + .rotationEffect(.degrees(fakeLandscape ? -90 : 0)) + .frame(width: proxy.size.width, height: proxy.size.height) + } + .background(Color.black) + .ignoresSafeArea() + .statusBarHidden(true) + .sheet(item: $explanationSentence) { sentence in + SentenceExplanationSheet( + mediaId: controller.currentItem?.id ?? "", + courseTitle: controller.currentItem?.title ?? "口语训练课程", + sentence: sentence + ) + } + } + + private var playerChrome: some View { ZStack { Color.black.ignoresSafeArea() PlayerSurfaceView(controller: controller) { isSwipeUp in @@ -95,13 +118,6 @@ struct FullscreenPlayerView: View { } .padding(16) } - .sheet(item: $explanationSentence) { sentence in - SentenceExplanationSheet( - mediaId: controller.currentItem?.id ?? "", - courseTitle: controller.currentItem?.title ?? "口语训练课程", - sentence: sentence - ) - } } @State private var progressDragging = false diff --git a/ios/OralTrainer/Views/RootView.swift b/ios/OralTrainer/Views/RootView.swift index f45305a..ef48f4c 100644 --- a/ios/OralTrainer/Views/RootView.swift +++ b/ios/OralTrainer/Views/RootView.swift @@ -115,7 +115,9 @@ struct RootView: View { FullscreenPlayerView(controller: controller) { exitFullscreen() } - .onAppear(perform: enterFullscreen) + .onAppear { + AppDelegate.lockOrientation(.landscape) + } } } @@ -519,26 +521,14 @@ struct RootView: View { // MARK: - Fullscreen private func enterFullscreen() { - AppDelegate.orientationLock = UIDevice.current.userInterfaceIdiom == .pad ? .all : .landscape - updateSupportedInterfaceOrientations() + AppDelegate.lockOrientation(.landscape) showFullscreenPlayer = true } private func exitFullscreen() { - AppDelegate.orientationLock = UIDevice.current.userInterfaceIdiom == .pad ? .all : .portrait - updateSupportedInterfaceOrientations() + let restored: UIInterfaceOrientationMask = + UIDevice.current.userInterfaceIdiom == .pad ? .all : .portrait + AppDelegate.lockOrientation(restored) showFullscreenPlayer = false } - - private func updateSupportedInterfaceOrientations() { - let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene } - let controllers = scenes.flatMap { $0.windows }.compactMap(\.rootViewController) - for controller in controllers { - if #available(iOS 16.0, *) { - controller.setNeedsUpdateOfSupportedInterfaceOrientations() - } else { - UIViewController.attemptRotationToDeviceOrientation() - } - } - } }