Skip to content

Instantly share code, notes, and snippets.

@pookjw
Created November 7, 2023 07:49
Show Gist options
  • Save pookjw/cf8f06605da0db483fd2c9c3578e68fb to your computer and use it in GitHub Desktop.
Save pookjw/cf8f06605da0db483fd2c9c3578e68fb to your computer and use it in GitHub Desktop.
import SwiftUI
private let associationKey = UnsafeMutablePointer<UInt8>.allocate(capacity: 1)
@MainActor
struct CustomUndoManagerView<Content: View>: UIViewControllerRepresentable {
private let undoManager: UndoManager
private let content: Content
init(undoManager: UndoManager, @ViewBuilder builder: () -> Content) {
self.undoManager = undoManager
self.content = builder()
}
func makeUIViewController(context: Context) -> UIViewController {
CustomUndoManagerViewController(undoManager: undoManager)
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
guard let viewController = uiViewController as? CustomUndoManagerViewController else {
return
}
viewController._undoManager = undoManager
weak var existingHostingController = objc_getAssociatedObject(viewController, associationKey) as? UIViewController
if let existingHostingController {
existingHostingController.willMove(toParent: nil)
existingHostingController.view.removeFromSuperview()
existingHostingController.removeFromParent()
}
let hostingController = UIHostingController(rootView: content)
objc_setAssociatedObject(viewController, associationKey, hostingController, .OBJC_ASSOCIATION_ASSIGN)
viewController.addChild(hostingController)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(hostingController.view)
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: viewController.view.topAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor)
])
hostingController.didMove(toParent: viewController)
}
}
@MainActor
private final class CustomUndoManagerViewController: UIViewController {
var _undoManager: UndoManager?
override var undoManager: UndoManager? {
_undoManager
}
init(undoManager: UndoManager) {
_undoManager = undoManager
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
@pookjw
Copy link
Author

pookjw commented Nov 7, 2023

CustomUndoManagerView(undoManager: UndoManager()) {
    ContentView()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment