I have built a half modal view that is used to display filters on a searchable list. The parent view has a text field that users can enter a search term in, and then a button will activate the half modal view to pop up for further functionality. The modal view works good, but I have now noticed that I can't enter text into the search field even when the modal is not actived... If I comment out the modal view then the text field works again.
Has anyone encountered this problem or know why it may be happening?
I have attached code here so you can see:
var body: some View {
VStack{
TextField("Search for Receipts", text: $searchInput, onCommit: {runSearch = true})
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
if isEditing {
Button(action: {
self.searchInput = ""
self.isEditing = false
self.runSearch = false
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
}
)
.onTapGesture {
isEditing = true
}
.padding(.horizontal, 20)
if !runSearch {
List{
ForEach(searchResults, id: \.self) { shop in
Button(action: {
self.searchInput = shop
self.runSearch = true
}, label: {
Text("\(shop)")
})
}
}
} else {
//Run search functionality here
}
}
.navigationBarTitle("SEARCH", displayMode: .inline)
.toolbar{
ToolbarItem(placement: .navigationBarTrailing){
Image(systemName: "slider.horizontal.3")
.foregroundColor(.gray)
.onTapGesture {
self.showFilter.toggle()
}
}
}
//Placement of the half modal sheet
.halfSheet(showSheet: $showFilter) {
FilterView(PriceLowHigh: $PriceLowHigh, PriceHighLow: $PriceHighLow, mostRecent: $mostRecent, byDate: $byDate, runSearch: $runSearch, dateFrom: $dateFrom, dateTo: $dateTo, closeFilter: $showFilter)
} onEnd: {
print("Dismiss")
}
}
}
And the code for the half modal:
//Creating a half modal view to display the filter options
extension View {
func halfSheet<SheetView: View>(showSheet: Binding<Bool>, @ViewBuilder sheetView: @escaping () ->SheetView, onEnd: @escaping()->())-> some View {
return self
.overlay(
HalfSheetHelper(sheetView: sheetView(), showSheet: showSheet, onEnd: onEnd)
)
}
}
//UIKit extension
struct HalfSheetHelper<SheetView: View>: UIViewControllerRepresentable {
var sheetView: SheetView
let controller = UIViewController()
@Binding var showSheet: Bool
var onEnd: ()->()
func makeCoordinator() -> Coordinator {
return 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)
} else {
uiViewController.dismiss(animated: true)
}
}
class Coordinator:NSObject, UISheetPresentationControllerDelegate {
var parent: HalfSheetHelper
init(parent: HalfSheetHelper) {
self.parent = parent
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
parent.showSheet = false
parent.onEnd()
}
}
}
class CustomHostingController<Content: View>: UIHostingController<Content>{
override func viewDidLoad() {
view.backgroundColor = .clear
//setting presentation controller properties
if let presentationController = presentationController as? UISheetPresentationController {
presentationController.detents = [
.medium()
//.large()
]
presentationController.prefersGrabberVisible = true
presentationController.preferredCornerRadius = 5.0
}
}
}