ios full screen

This commit is contained in:
2026-09-14 17:48:42 +08:00
parent 3aaa9f4229
commit 2a7f24b1bd
5 changed files with 66 additions and 24 deletions

View File

@@ -9,4 +9,38 @@ final class AppDelegate: NSObject, UIApplicationDelegate {
) -> UIInterfaceOrientationMask { ) -> UIInterfaceOrientationMask {
AppDelegate.orientationLock 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 }
}
}
} }

View File

@@ -33,6 +33,8 @@
<string>需要麦克风权限才能进行录音评测</string> <string>需要麦克风权限才能进行录音评测</string>
<key>UILaunchScreen</key> <key>UILaunchScreen</key>
<dict/> <dict/>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>

View File

@@ -9,6 +9,29 @@ struct FullscreenPlayerView: View {
@State private var explanationSentence: SentenceBoundary? @State private var explanationSentence: SentenceBoundary?
var body: some View { 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 { ZStack {
Color.black.ignoresSafeArea() Color.black.ignoresSafeArea()
PlayerSurfaceView(controller: controller) { isSwipeUp in PlayerSurfaceView(controller: controller) { isSwipeUp in
@@ -95,13 +118,6 @@ struct FullscreenPlayerView: View {
} }
.padding(16) .padding(16)
} }
.sheet(item: $explanationSentence) { sentence in
SentenceExplanationSheet(
mediaId: controller.currentItem?.id ?? "",
courseTitle: controller.currentItem?.title ?? "口语训练课程",
sentence: sentence
)
}
} }
@State private var progressDragging = false @State private var progressDragging = false

View File

@@ -115,7 +115,9 @@ struct RootView: View {
FullscreenPlayerView(controller: controller) { FullscreenPlayerView(controller: controller) {
exitFullscreen() exitFullscreen()
} }
.onAppear(perform: enterFullscreen) .onAppear {
AppDelegate.lockOrientation(.landscape)
}
} }
} }
@@ -519,26 +521,14 @@ struct RootView: View {
// MARK: - Fullscreen // MARK: - Fullscreen
private func enterFullscreen() { private func enterFullscreen() {
AppDelegate.orientationLock = UIDevice.current.userInterfaceIdiom == .pad ? .all : .landscape AppDelegate.lockOrientation(.landscape)
updateSupportedInterfaceOrientations()
showFullscreenPlayer = true showFullscreenPlayer = true
} }
private func exitFullscreen() { private func exitFullscreen() {
AppDelegate.orientationLock = UIDevice.current.userInterfaceIdiom == .pad ? .all : .portrait let restored: UIInterfaceOrientationMask =
updateSupportedInterfaceOrientations() UIDevice.current.userInterfaceIdiom == .pad ? .all : .portrait
AppDelegate.lockOrientation(restored)
showFullscreenPlayer = false 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()
}
}
}
} }