Created
August 23, 2021 10:50
-
-
Save darrarski/3dd9679646397bf82df8b22ddabce2cd to your computer and use it in GitHub Desktop.
SwiftUI view modifier that performs action when UIInterfaceOrientation changes
This file contains 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 | |
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