linphone-ios/Linphone/UI/Main/Fragments/CustomBottomSheet.swift
2023-10-30 12:07:31 +01:00

98 lines
3.1 KiB
Swift

/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import SwiftUI
extension View {
func halfSheet<Content: View>(
showSheet: Binding<Bool>,
@ViewBuilder content: @escaping () -> Content,
onDismiss: @escaping () -> Void
) -> some View {
return self
.background(
HalfSheetHelper(sheetView: content(), showSheet: showSheet, onDismiss: onDismiss)
)
}
}
struct HalfSheetHelper<Content: View>: UIViewControllerRepresentable {
var sheetView: Content
let controller: UIViewController = UIViewController()
@Binding var showSheet: Bool
var onDismiss: () -> Void
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeUIViewController(context: Context) -> UIViewController {
controller.view.backgroundColor = .clear
return controller
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
if showSheet {
let sheetController = CustomHostingController(rootView: sheetView)
sheetController.presentationController?.delegate = context.coordinator
uiViewController.present(sheetController, animated: true)
}
}
final class Coordinator: NSObject, UISheetPresentationControllerDelegate {
var parent: HalfSheetHelper
init(parent: HalfSheetHelper) {
self.parent = parent
}
func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
parent.showSheet = false
}
}
}
final class CustomHostingController<Content: View>: UIHostingController<Content> {
override func viewDidLoad() {
view.backgroundColor = .clear
if let presentationController = presentationController as? UISheetPresentationController {
presentationController.detents = [
.medium()
]
presentationController.prefersGrabberVisible = false
presentationController.prefersScrollingExpandsWhenScrolledToEdge = false
presentationController.preferredCornerRadius = 30
}
}
}
public struct LazyView<Content: View>: View {
private let build: () -> Content
public init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
public var body: Content {
build()
}
}