Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrarski/93fac5a77fa8a25634b9b07741b4ba59 to your computer and use it in GitHub Desktop.
Save darrarski/93fac5a77fa8a25634b9b07741b4ba59 to your computer and use it in GitHub Desktop.
SwiftUI view modifier that performs action whenever UIInterfaceOrientation reported by UIViewController changes
import SwiftUI
struct InterfaceOrientationObservingViewModifier: ViewModifier {
let onChange: (UIInterfaceOrientation) -> Void
func body(content: Content) -> some View {
content.background(InterfaceOrientationObservingView(onChange: onChange))
}
}
extension View {
func onInterfaceOrientationChange(perform: @escaping (UIInterfaceOrientation) -> Void) -> some View {
modifier(InterfaceOrientationObservingViewModifier(onChange: perform))
}
}
private struct InterfaceOrientationObservingView: UIViewControllerRepresentable {
let onChange: (UIInterfaceOrientation) -> Void
func makeUIViewController(context: Context) -> InterfaceOrientationObservingViewController {
InterfaceOrientationObservingViewController(onChange: onChange)
}
func updateUIViewController(_ uiViewController: InterfaceOrientationObservingViewController, context: Context) {}
}
private final class InterfaceOrientationObservingViewController: UIViewController {
init(onChange: @escaping (UIInterfaceOrientation) -> Void) {
self.onChange = onChange
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) { nil }
let onChange: (UIInterfaceOrientation) -> Void
var lastOrientation: UIInterfaceOrientation?
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
perform()
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
perform()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
perform()
}
func perform() {
guard let orientation = view.window?.windowScene?.interfaceOrientation else { return }
guard lastOrientation == nil || lastOrientation != orientation else { return }
lastOrientation = orientation
onChange(orientation)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment