106 lines
3.1 KiB
Swift
106 lines
3.1 KiB
Swift
//
|
|
// Swiftfin is subject to the terms of the Mozilla Public
|
|
// License, v2.0. If a copy of the MPL was not distributed with this
|
|
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
//
|
|
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct RotateContentView: UIViewRepresentable {
|
|
|
|
@ObservedObject
|
|
var proxy: Proxy
|
|
|
|
func makeUIView(context: Context) -> UIRotateContentView {
|
|
UIRotateContentView(initialView: nil, proxy: proxy)
|
|
}
|
|
|
|
func updateUIView(_ uiView: UIRotateContentView, context: Context) {}
|
|
|
|
class Proxy: ObservableObject {
|
|
|
|
weak var rotateContentView: UIRotateContentView?
|
|
|
|
func update(_ content: () -> any View) {
|
|
|
|
let newHostingController = UIHostingController(rootView: AnyView(content()), ignoreSafeArea: true)
|
|
newHostingController.view.translatesAutoresizingMaskIntoConstraints = false
|
|
newHostingController.view.backgroundColor = .clear
|
|
|
|
rotateContentView?.update(with: newHostingController.view)
|
|
}
|
|
}
|
|
}
|
|
|
|
class UIRotateContentView: UIView {
|
|
|
|
private(set) var currentView: UIView?
|
|
var proxy: RotateContentView.Proxy
|
|
|
|
init(initialView: UIView?, proxy: RotateContentView.Proxy) {
|
|
self.proxy = proxy
|
|
|
|
super.init(frame: .zero)
|
|
|
|
proxy.rotateContentView = self
|
|
|
|
guard let initialView else { return }
|
|
|
|
initialView.translatesAutoresizingMaskIntoConstraints = false
|
|
initialView.alpha = 0
|
|
|
|
addSubview(initialView)
|
|
NSLayoutConstraint.activate([
|
|
initialView.topAnchor.constraint(equalTo: topAnchor),
|
|
initialView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
initialView.leftAnchor.constraint(equalTo: leftAnchor),
|
|
initialView.rightAnchor.constraint(equalTo: rightAnchor),
|
|
])
|
|
|
|
self.currentView = initialView
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func update(with newView: UIView?) {
|
|
|
|
guard let newView else {
|
|
UIView.animate(withDuration: 0.3) {
|
|
self.currentView?.alpha = 0
|
|
} completion: { _ in
|
|
self.currentView?.removeFromSuperview()
|
|
self.currentView = newView
|
|
}
|
|
return
|
|
}
|
|
|
|
newView.translatesAutoresizingMaskIntoConstraints = false
|
|
newView.alpha = 0
|
|
|
|
addSubview(newView)
|
|
NSLayoutConstraint.activate([
|
|
newView.topAnchor.constraint(equalTo: topAnchor),
|
|
newView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
newView.leftAnchor.constraint(equalTo: leftAnchor),
|
|
newView.rightAnchor.constraint(equalTo: rightAnchor),
|
|
])
|
|
|
|
UIView.animate(withDuration: 0.3) {
|
|
newView.alpha = 1
|
|
self.currentView?.alpha = 0
|
|
} completion: { _ in
|
|
self.currentView?.removeFromSuperview()
|
|
self.currentView = newView
|
|
}
|
|
}
|
|
|
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
currentView?.hitTest(point, with: event)
|
|
}
|
|
}
|