Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrarski/3dd9679646397bf82df8b22ddabce2cd to your computer and use it in GitHub Desktop.
Save darrarski/3dd9679646397bf82df8b22ddabce2cd to your computer and use it in GitHub Desktop.
SwiftUI view modifier that performs action when UIInterfaceOrientation changes
import SwiftUI
public extension View {
/// Perform action when interface orientation of the view changes
/// - Parameter perform: Action to perform
/// - Returns: Modified view
func onInterfaceOrientationChange(perform: @escaping (UIInterfaceOrientation) -> Void) -> some View {
modifier(OnInterfaceOrientationChangeViewModifier(onChange: perform))
}
}
private struct OnInterfaceOrientationChangeViewModifier: ViewModifier {
let onChange: (UIInterfaceOrientation) -> Void
func body(content: Content) -> some View {
content.background(OnInterfaceOrientationChangeView(onChange: onChange))
}
}
private struct OnInterfaceOrientationChangeView: UIViewControllerRepresentable {
let onChange: (UIInterfaceOrientation) -> Void
func makeUIViewController(context: Context) -> OnInterfaceOrientationChangeViewController {
OnInterfaceOrientationChangeViewController(onChange: onChange)
}
func updateUIViewController(_ uiViewController: OnInterfaceOrientationChangeViewController, context: Context) {}
}
private final class OnInterfaceOrientationChangeViewController: 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()
}
func perform() {
guard let orientation = view.window?.windowScene?.interfaceOrientation else { return }
guard lastOrientation == nil || lastOrientation != orientation else { return }
lastOrientation = orientation
onChange(orientation)
}
}
// MARK: - Example
struct ExampleView: View {
var body: some View {
Text("Hello, World")
.onInterfaceOrientationChange { orientation in
print("^^^ \(orientation.rawValue)")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment