Skip to content

Instantly share code, notes, and snippets.

@donnywals
Last active June 30, 2021 07:17
Show Gist options
  • Save donnywals/3058ed489e35524dacfede1a3cc765ff to your computer and use it in GitHub Desktop.
Save donnywals/3058ed489e35524dacfede1a3cc765ff to your computer and use it in GitHub Desktop.
import UIKit
import SwiftUI
// Hacky workaround, use at your own risk and all that
struct BottomSheetPresenter<Content>: UIViewRepresentable where Content: View{
let label: String
let content: Content
let detents: [UISheetPresentationController.Detent]
init(_ label: String, detents: [UISheetPresentationController.Detent], @ViewBuilder content: () -> Content) {
self.label = label
self.content = content()
self.detents = detents
}
func makeUIView(context: UIViewRepresentableContext<BottomSheetPresenter>) -> UIButton {
let button = UIButton(type: .system)
button.setTitle(label, for: .normal)
button.addAction(UIAction { _ in
let hostingController = UIHostingController(rootView: content)
let viewController = UIBottomSheetWrapper(detents: detents)
viewController.addChild(hostingController)
viewController.view.addSubview(hostingController.view)
hostingController.view.pinToEdgesOf(viewController.view)
hostingController.didMove(toParent: viewController)
button.window?.rootViewController?.present(viewController, animated: true)
}, for: .touchUpInside)
print("make...")
return button
}
func updateUIView(_ uiView: UIButton, context: Context) {
// no updates
}
func makeCoordinator() -> Void {
return ()
}
}
extension BottomSheetPresenter {
class UIBottomSheetWrapper: UIViewController {
let detents: [UISheetPresentationController.Detent]
init(detents: [UISheetPresentationController.Detent]) {
self.detents = detents
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("No Storyboards")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .gray
if let sheetController = self.presentationController as? UISheetPresentationController {
sheetController.detents = detents
}
}
}
}
extension UIView {
func pinToEdgesOf(_ other: UIView) {
translatesAutoresizingMaskIntoConstraints = false
leftAnchor.constraint(equalTo: other.leftAnchor).isActive = true
topAnchor.constraint(equalTo: other.topAnchor).isActive = true
rightAnchor.constraint(equalTo: other.rightAnchor).isActive = true
bottomAnchor.constraint(equalTo: other.bottomAnchor).isActive = true
}
}
// Usage
struct ContentView: View {
var body: some View {
VStack {
BottomSheetPresenter("Tap me for a bottom sheet!!", detents: [.medium(), .large()]) {
VStack {
Text("This is a test")
Rectangle()
.frame(width: 300, height: 300, alignment: .leading)
.foregroundColor(.blue)
}
}
}
}
}
@donnywals
Copy link
Author

Thanks! 😁 I'll modify the gist to use your suggestion

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