Files
legado-ios/App/Features/Reader/ReaderSupport.swift
T

89 lines
3.0 KiB
Swift

import SwiftUI
import UIKit
struct ReaderInteractivePopEnabler: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> Controller {
Controller()
}
func updateUIViewController(_ uiViewController: Controller, context: Context) {
uiViewController.enableInteractivePopIfAvailable()
}
static func dismantleUIViewController(_ uiViewController: Controller, coordinator: Void) {
uiViewController.restoreInteractivePopDelegate()
}
final class Controller: UIViewController {
private weak var popGesture: UIGestureRecognizer?
private var previousDelegate: (any UIGestureRecognizerDelegate)?
private var releasedDelegate = false
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
enableInteractivePopIfAvailable()
}
func enableInteractivePopIfAvailable() {
guard let navigationController,
navigationController.viewControllers.count > 1,
let gesture = navigationController.interactivePopGestureRecognizer else { return }
if gesture.delegate != nil {
previousDelegate = gesture.delegate
gesture.delegate = nil
releasedDelegate = true
}
gesture.isEnabled = true
popGesture = gesture
}
func restoreInteractivePopDelegate() {
guard releasedDelegate, let popGesture, popGesture.delegate == nil else { return }
popGesture.delegate = previousDelegate
previousDelegate = nil
releasedDelegate = false
}
}
}
struct ReaderMenuDismissShape: Shape {
var leadingExclusion: CGFloat = 24
func path(in rect: CGRect) -> Path {
Path(CGRect(
x: min(max(leadingExclusion, 0), rect.width),
y: 0,
width: max(rect.width - leadingExclusion, 0),
height: rect.height
))
}
}
@MainActor enum ReaderScreenOrientation {
static private(set) var supportedOrientations: UIInterfaceOrientationMask = .allButUpsideDown
static func apply(_ value: String) {
let mask: UIInterfaceOrientationMask = switch value {
case "1": .portrait
case "2": .landscape
case "3": .all
case "4": .portraitUpsideDown
case "5": .landscapeLeft
default: .allButUpsideDown
}
supportedOrientations = mask
guard let scene = UIApplication.shared.connectedScenes
.compactMap({ $0 as? UIWindowScene })
.first(where: { $0.activationState == .foregroundActive }) else { return }
if #available(iOS 16.0, *) {
scene.requestGeometryUpdate(.iOS(interfaceOrientations: mask)) { _ in }
scene.windows.first?.rootViewController?.setNeedsUpdateOfSupportedInterfaceOrientations()
} else {
UIViewController.attemptRotationToDeviceOrientation()
}
}
static func restoreApplicationDefault() { apply("0") }
}