Created
February 18, 2022 13:49
-
-
Save darrarski/93fac5a77fa8a25634b9b07741b4ba59 to your computer and use it in GitHub Desktop.
SwiftUI view modifier that performs action whenever UIInterfaceOrientation reported by UIViewController changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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