在 Swift 的导航栏中获取搜索栏

Posted

技术标签:

【中文标题】在 Swift 的导航栏中获取搜索栏【英文标题】:Get search bar in navigation bar in Swift 【发布时间】:2014-11-04 01:57:11 【问题描述】:

所以我已经尝试了所有尝试将搜索栏放入 Swift 导航栏中的方法。但遗憾的是,我还没有让它工作,只是还......

对于那些不知道我在说什么的人,我正在尝试做这样的事情

注意导航栏中的搜索栏。所以这就是我目前正在使用的

self.searchDisplayController?.displaysSearchBarInNavigationBar = true

我在viewDidLoad 中弹出了它,然后当我加载我看到的应用程序时,只是一个空的导航栏.... :( 有什么想法吗?

【问题讨论】:

【参考方案1】:

试试这个

let leftNavBarButton = UIBarButtonItem(customView:Yoursearchbar)
  self.navigationItem.leftBarButtonItem = leftNavBarButton

更新

你保留了一个懒惰的 UISearchBar 属性

lazy   var searchBar:UISearchBar = UISearchBar(frame: CGRectMake(0, 0, 200, 20))

在 viewDidLoad 中

searchBar.placeholder = "Your placeholder"
var leftNavBarButton = UIBarButtonItem(customView:searchBar)
self.navigationItem.leftBarButtonItem = leftNavBarButton

如果你想使用故事板 只需将您的搜索栏拖动为插座,然后用您的插座搜索栏替换惰性属性

【讨论】:

如何识别Yoursearchbar 到目前为止一切顺利。但是我将如何添加占位符?有什么办法通过故事板? 你只需更改搜索栏的属性添加一个占位符。我更新答案 嗨,你能告诉我整个代码吗?我不太了解lazy 部分 谁能解释一下lazy是做什么的?懒惰的 var searchBar 与 var searchBar 有什么区别【参考方案2】:
    // create the search bar programatically since you won't be
    // able to drag one onto the navigation bar
    searchBar = UISearchBar()
    searchBar.sizeToFit()

    // the UIViewController comes with a navigationItem property
    // this will automatically be initialized for you if when the
    // view controller is added to a navigation controller's stack
    // you just need to set the titleView to be the search bar
    navigationItem.titleView = searchBar

【讨论】:

这比任何其他解决方案都要好。 @antonio081014,兄弟你能帮我看看我的问题***.com/questions/46375778/…吗?【参考方案3】:

Swift 5、XCode 11、Storyboard 方式,因此您可以通过 storyboard 轻松添加所有搜索栏属性,并且您的视图控制器类中有 less code

1.) 将您的搜索栏视图添加为视图控制器中的外部视图。

2.) 将 searchBarView 连接到您的视图控制器。

3.) 将您的 searchBarView 添加到您的导航栏标题项。

navigationItem.titleView = searchBarView

结果:

【讨论】:

我希望我能更多地支持这个。我不知道你能做到这一点! @Egzon 这个正在将导航栏的大小从 44 更改为 56。因此,当我返回上一个视图控制器时,导航控制器的闪烁会更新到其原始大小 44。关于它的任何建议请。 嗨@MiteshDobareeya,我会在下周检查有什么问题并回复你。您是否在同一个 UINavigationViewController 中推送视图控制器? @EgzonP。是的,我将它推入同一个 UINavigationViewController。主根视图控制器导航栏的大小完美为 44。当我推动第二个视图控制器并添加搜索栏时,导航栏到第二个 vc 的大小增加到 56。所以当我弹出到第一个 vc 时,它的导航栏得到眨眼。【参考方案4】:

在您的视图控制器中:

lazy var searchBar = UISearchBar(frame: CGRectZero)

override func viewDidLoad() 
    super.viewDidLoad()

    searchBar.placeholder = "Search"

    navigationItem.titleView = searchBar

这样做,通过设置navigationItem.titleView,搜索栏在iPhone 和iPad 设备上自动居中。注意:仅在 v8.4 和 v9.0 上测试过

适用于 SWIFT 3

lazy var searchBar = UISearchBar(frame: CGRect.zero)

【讨论】:

当用户点击“取消”按钮时,如何将其从 navigationItem.titleView 中移除? 同样的问题 ^ 如果你说的是搜索栏的取消按钮,那我就别想了。实现 UISearchBarDelegate 函数 searchBarCancelButtonClicked(:),在该函数中调用 navigationItem.titleView = nil。如果这就是您所说的“删除它”,这应该删除搜索栏。对于正常的搜索栏功能,还要确保实现 searchBarSearchButtonClicked(:) 添加 searchBar.resignFirstResponder() 以在单击搜索按钮(或通过按返回键启动)时移除键盘 更新了 Swift 3 的代码:lazy var searchBar = UISearchBar(frame: CGRect.zero)【参考方案5】:

2019 年,你应该使用 UISearchController。

override func viewDidLoad() 
    super.viewDidLoad()

    let searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self.viewModel
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Search artists"
    self.navigationItem.searchController = searchController
    self.definesPresentationContext = true

有些类应该符合 UISearchResultsUpdating。我通常将此作为扩展添加到我的 ViewModel。

extension ArtistSearchViewModel: UISearchResultsUpdating 

func updateSearchResults(for searchController: UISearchController) 
    print("Searching with: " + (searchController.searchBar.text ?? ""))
    let searchText = (searchController.searchBar.text ?? "")
    self.currentSearchText = searchText
    search()
    

这将产生如下内容:

【讨论】:

这个解决方案工作正常,但是当我的 tableView 只有几行并且高度显然不够时,我遇到了问题。当我向下滚动时,搜索栏会消失,然后我无法通过再次向上滚动来恢复它,因为它不需要滚动来显示所有行。任何想法如何解决这个问题? @JDK 遗憾的是,我不确定。 :(您可以尝试观察Pull to Refresh,当它被触发时,您可以尝试手动告诉UISearchBar显示。我只是提出一个想法。 @JDK92 我知道这是一个迟到的答案,但如果你希望搜索栏始终保持粘性,你可以使用这个 navigationItem.hidesSearchBarWhenScrolling = false【参考方案6】:

适用于 ios 11 及更高版本

navigationItem.searchController = searchController

适用于 iOS 10 及更低版本

navigationItem.titleView = searchController.searchBar;

或者您可以按照this answer 中的说明将其分配为 leftBarButtonItem

【讨论】:

【参考方案7】:

适用于 Swift 5 或字母

另外,您可以使用此代码。 完全以编程方式

import UIKit

class SearchTableViewController: UITableViewController 

private lazy var searchController: UISearchController = 
    let sc = UISearchController(searchResultsController: nil)
    sc.searchResultsUpdater = self
    sc.delegate = self
    sc.obscuresBackgroundDuringPresentation = false
    sc.searchBar.placeholder = "Enter A Compiny Name Or Symbole"
    sc.searchBar.autocapitalizationType = .allCharacters
    return sc
()

override func viewDidLoad() 
    super.viewDidLoad()
    setupNavigationBar()


   private func setupNavigationBar() 
       navigationItem.searchController = searchController
   

 

// MARK: - UISearchResult Updating and UISearchControllerDelegate  Extension
  extension SearchTableViewController: UISearchResultsUpdating, UISearchControllerDelegate 
    func updateSearchResults(for searchController: UISearchController) 
    
    
 

【讨论】:

【参考方案8】:
    let searchBar = UISearchBar()
    searchBar.sizeToFit()
    searchBar.placeholder = ""
    self.navigationController?.navigationBar.topItem?.titleView = searchBar

【讨论】:

【参考方案9】:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 

    searchBar.endEditing(true)
    searchBar.text = nil
    print("## search btn clicked : \(searchBar.text ?? "")")
 

【讨论】:

感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。【参考方案10】:

适用于 Swift 4 和 5。

let searchBar = UISearchBar()
self.navigationItem.titleView = searchBar

let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: nil)

cancelButton.tintColor = #colorLiteral

searchBar.tintColor = #colorLiteral

self.navigationItem.rightBarButtonItem = cancelButton

【讨论】:

【参考方案11】:

将 SearchBar 设置为 titleView,将 navigationBar 的高度更改为 56。要解决此问题,您可以将 searchBar 嵌入视图并将其设置为 titleView。

    var offset: CGFloat = 20

    // If VC is pushed, back button should be visible
    if navigationController?.navigationBar.backItem != nil 
        offset = 40
    

    let customFrame = CGRect(x: 0, y: 0, width: view.frame.size.width - offset, height: 44.0)
    let searchBarContainer = UIView(frame: customFrame)
    searchBar = UISearchBar(frame: customFrame)
    searchBarContainer.addSubview(searchBar)
    navigationItem.titleView = searchBarContainer

【讨论】:

以上是关于在 Swift 的导航栏中获取搜索栏的主要内容,如果未能解决你的问题,请参考以下文章

iOS:在导航栏中显示搜索栏时隐藏范围栏

Ios Swift:在自定义标签栏中显示导航栏

导航栏中的 Swift 自定义后退按钮

导航栏中的 iOS 搜索栏

iOS 11 在导航栏中自定义搜索栏

在导航栏中自动添加“返回”按钮