我想在导航栏中添加搜索栏,但我不知道如何在同一个 HStack
中使用带有侧边栏图标的搜索栏。我将示例屏幕截图与 ContentView 代码放在一起。任何帮助将不胜感激。
截图:
内容视图:
struct ContentView: View {
@State private var isShowing = false
var body: some View {
ZStack {
if isShowing {
SideMenuView(isShowing: $isShowing)
}
TabView {
NavigationView {
HomeView()
.navigationBarItems(leading: Button(action: {
withAnimation(.spring()) {
isShowing.toggle()
}
} , label: {
Image(systemName: "list.bullet")
}))
}
.tabItem {
Image(systemName: "1.circle")
Text("Page 1")
}
NavigationView {
HomeTwoView()
.navigationBarItems(leading: Button(action: {
withAnimation(.spring()) {
isShowing.toggle()
}
} , label: {
Image(systemName: "list.bullet")
}))
}
.tabItem {
Image(systemName: "2.circle")
Text("Page 2")
}
}
.edgesIgnoringSafeArea(.bottom)
//.cornerRadius(isShowing ? 20 : 0) //<< disabled due to strange effect
.offset(x: isShowing ? 300 : 0, y: isShowing ? 44: 0)
.scaleEffect(isShowing ? 0.8 : 1)
}.onAppear {
isShowing=false
}
}
}
答案 0 :(得分:2)
正如我在评论中提到的,这在 SwiftUI (2.0) 中是不可能的。您可以做的是与 UIKit 集成。
class UIKitSearchBar: NSObject, ObservableObject {
@Published var text: String = ""
let searchController = UISearchController(searchResultsController: nil)
override init() {
super.init()
self.searchController.obscuresBackgroundDuringPresentation = false
self.searchController.definesPresentationContext = true
self.searchController.searchResultsUpdater = self
}
}
extension UIKitSearchBar: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
// Publish search bar text changes.
if let searchBarText = searchController.searchBar.text {
self.text = searchBarText
}
}
}
struct SearchBarModifier: ViewModifier {
let searchBar: UIKitSearchBar
func body(content: Content) -> some View {
content
.overlay(
ViewControllerResolver { viewController in
viewController.navigationItem.searchController = self.searchBar.searchController
}
.frame(width: 0, height: 0)
)
}
}
extension View {
func add(_ searchBar: UIKitSearchBar) -> some View {
return self.modifier(SearchBarModifier(searchBar: searchBar))
}
}
final class ViewControllerResolver: UIViewControllerRepresentable {
let onResolve: (UIViewController) -> Void
init(onResolve: @escaping (UIViewController) -> Void) {
self.onResolve = onResolve
}
func makeUIViewController(context: Context) -> ParentResolverViewController {
ParentResolverViewController(onResolve: onResolve)
}
func updateUIViewController(_ uiViewController: ParentResolverViewController, context: Context) { }
}
class ParentResolverViewController: UIViewController {
let onResolve: (UIViewController) -> Void
init(onResolve: @escaping (UIViewController) -> Void) {
self.onResolve = onResolve
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
if let parent = parent {
onResolve(parent)
}
}
}
struct Example: View {
@StateObject var searchBar = UIKitSearchBar()
var body: some View {
NavigationView {
Text("Example")
.add(searchBar)
.navigationTitle("Example")
}
}
}
在我自己的项目中,我使用计算属性来过滤内容,它对您也有帮助。这是我的代码:
var filteredExams: [Exam] {
examModel.exams.filter({ searchBar.text.isEmpty || $0.examName.localizedStandardContains(searchBar.text)})
}