【问题标题】:How to prevent search bar from disappearing on scroll? iOS Swift如何防止搜索栏在滚动时消失? iOS 斯威夫特
【发布时间】:2015-07-29 13:49:44
【问题描述】:

我正在创建一个联系人应用程序。我的表格视图顶部有一个滚动条。

当我向下滚动时,搜索栏消失。

如何防止搜索栏在滚动时消失?我希望它始终保持在页面顶部,就像第一张图片一样。

这是我的故事板的图片:

如果解决方案不在情节提要中,这是我的视图控制器代码:

class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {

    //manages search bar
    var searchController:UISearchController!

    var contacts = [Contact]()

    //array to hold contacts that match the search results
    var filteredContacts = [Contact]()

    override func viewDidLoad() {

        super.viewDidLoad()

        //initialize the defaults manager class
        NSUserDefaultsManager.initializeDefaults()

        //search controller
        searchController = UISearchController(searchResultsController: nil)
        searchController.searchBar.sizeToFit()
        tableView.tableHeaderView = searchController.searchBar
        definesPresentationContext = true

        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false

        //load the contacts
        title = "Contacts"

        tableView.backgroundView = UIImageView(image: UIImage(named: "valblur15"))

        contacts = [Contact]()
        let api = ContactAPI()
        api.loadContacts(didLoadContacts)

    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        //reload the table view to check for new contacts
        tableView.reloadData()

        //set the color of the nav bar to valbruna yellow
        navigationController?.navigationBar.backgroundColor = UIColor(red: 254.0/255.0, green: 196.0/255.0, blue: 37.0/255.0, alpha: 0.95)

    }

    //MARK: -Helper Methods

    // Uupdate searching results
    func updateSearchResultsForSearchController(searchController: UISearchController) {

        let searchText = searchController.searchBar.text
        filterContentForSearchText(searchText)
        tableView.reloadData()

    }

    func filterList() { // should probably be called sort and not filter

        //sort contacts from a-z
        contacts.sort() { $0.name < $1.name }

        //remove contacts whose locations are nil
        contacts = contacts.filter() { $0.location != "nil"}

        //remove contacts whose titles phone email and department are all nil
        contacts = contacts.filter() {
            if($0.title != "" || $0.phone != "" || $0.email != "" || $0.department != ""){
                return true
            }
            return false
        }


        tableView.reloadData()
    }

    func didLoadContacts(contacts: [Contact]){
        self.contacts = contacts
        filterList()
        tableView.reloadData()
    }

    //MARK: -Table View

    //set number opf sections in table view
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    //delegeate that tells tabel view how many cells to have
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //return size of array

        //if searching show count of filtered contacts
        if (searchController.active){

            return self.filteredContacts.count

        }else{

            return self.contacts.count

        }

    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = self.tableView.dequeueReusableCellWithIdentifier("customcell") as! CustomCell //from the customcell class

        //change color of cell text label
        cell.textLabel?.textColor = UIColor.blackColor()
        cell.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 0.8)

        let contact : Contact

        //if users is searching then return filtered contacts
        if (searchController.active){

            contact = self.filteredContacts[indexPath.row]

        }else{

            contact = self.contacts[indexPath.row]

        }


        //handel assignment of text
        cell.textLabel?.text = contact.name

        //retrieve from customcell class
        cell.contact = contact

        return cell
    }


    //MARK: -Search

    func filterContentForSearchText(searchText: String, scope: String = "Title")
    {
        self.filteredContacts = self.contacts.filter({( contact: Contact) -> Bool in

            //filters contacts array

            var categoryMatch = (scope == "Title")
            var stringMatch = contact.name?.rangeOfString(searchText)

            return categoryMatch && (stringMatch != nil)

        })
    }

    func searchDisplayController(controller: UISearchController, shouldReloadTableForSearchString searchString: String!) -> Bool {

        self.filterContentForSearchText(searchString, scope: "Title")

        return true

    }


    func searchDisplayController(controller: UISearchController, shouldReloadTableForSearchScope searchOption: Int) -> Bool {

        self.filterContentForSearchText(self.searchController!.searchBar.text, scope: "Title")

        return true

    }

    //MARK: -Segue

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if(segue.identifier == "detailview"){
            let cell = sender as! CustomCell
            let detailView = segue.destinationViewController as! DetailViewController
            detailView.preContact = cell.contact

        }
    }

}

编辑 1:

以下是我根据 Ryosuke Hiramatsu 的解决方案采取的步骤:

  1. Command X 表格视图。
  2. 添加视图。
  3. Command V 将表格视图转换为新视图。
  4. 在视图控制器中,将 UITableViewController 更改为 UITableView
  5. 向视图控制器添加一个名为 table view 的 outlet。
  6. 删除表视图函数中的覆盖。
  7. 去掉这行代码:tableView.tableHeaderView = searchController.searchBar
  8. 返回故事板并将搜索栏移出表格视图。它会出现在表格视图的后面。
  9. 向下移动表格视图并向上移动搜索栏。
  10. 添加必要的约束。

我的视图现在看起来像这样:

当我向下滚动时:

我的故事板:

最后是我更新的视图控制器代码:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {


@IBOutlet var tableView: UITableView!


//manages search bar
var searchController:UISearchController!

var contacts = [Contact]()

//array to hold contacts that match the search results
var filteredContacts = [Contact]()

override func viewDidLoad() {

    super.viewDidLoad()

    //initialize the defaults manager class
    NSUserDefaultsManager.initializeDefaults()

    //search controller
    searchController = UISearchController(searchResultsController: nil)
    searchController.searchBar.sizeToFit()
    definesPresentationContext = true

    tableView.tableHeaderView = searchController.searchBar

    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false

    //load the contacts
    title = "Valbruna Contacts"

    tableView.backgroundView = UIImageView(image: UIImage(named: "valblur15"))

    contacts = [Contact]()
    let api = ContactAPI()
    api.loadContacts(didLoadContacts)

}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //reload the table view to check for new contacts
    tableView.reloadData()

    //set the color of the nav bar to valbruna yellow
    navigationController?.navigationBar.backgroundColor = UIColor(red: 254.0/255.0, green: 196.0/255.0, blue: 37.0/255.0, alpha: 0.95)

}

//MARK: -Helper Methods

// Uupdate searching results
func updateSearchResultsForSearchController(searchController: UISearchController) {

    let searchText = searchController.searchBar.text
    filterContentForSearchText(searchText)
    tableView.reloadData()

}

func filterList() { // should probably be called sort and not filter

    //sort contacts from a-z
    contacts.sort() { $0.name < $1.name }

    //remove contacts whose locations are nil
    contacts = contacts.filter() { $0.location != "nil"}

    //remove contacts whose titles phone email and department are all nil
    contacts = contacts.filter() {
        if($0.title != "" || $0.phone != "" || $0.email != "" || $0.department != ""){
            return true
        }
        return false
    }


    tableView.reloadData()
}

func didLoadContacts(contacts: [Contact]){
    self.contacts = contacts
    filterList()
    tableView.reloadData()
}

//MARK: -Table View

//set number opf sections in table view
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

//delegeate that tells tabel view how many cells to have
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //return size of array

    //if searching show count of filtered contacts
    if (searchController.active){

        return self.filteredContacts.count

    }else{

        return self.contacts.count

    }

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = self.tableView.dequeueReusableCellWithIdentifier("customcell") as! CustomCell //from the customcell class

    //change color of cell text label
    cell.textLabel?.textColor = UIColor.blackColor()
    cell.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 0.8)

    let contact : Contact

    //if users is searching then return filtered contacts
    if (searchController.active){

        contact = self.filteredContacts[indexPath.row]

    }else{

        contact = self.contacts[indexPath.row]

    }


    //handel assignment of text
    cell.textLabel?.text = contact.name

    //retrieve from customcell class
    cell.contact = contact

    return cell
}


//MARK: -Search

func filterContentForSearchText(searchText: String, scope: String = "Title")
{
    self.filteredContacts = self.contacts.filter({( contact: Contact) -> Bool in

        //filters contacts array

        var categoryMatch = (scope == "Title")
        var stringMatch = contact.name?.rangeOfString(searchText)

        return categoryMatch && (stringMatch != nil)

    })
}

func searchDisplayController(controller: UISearchController, shouldReloadTableForSearchString searchString: String!) -> Bool {

    self.filterContentForSearchText(searchString, scope: "Title")

    return true

}


func searchDisplayController(controller: UISearchController, shouldReloadTableForSearchScope searchOption: Int) -> Bool {

    self.filterContentForSearchText(self.searchController!.searchBar.text, scope: "Title")

    return true

}

//MARK: -Segue

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if(segue.identifier == "detailview"){
        let cell = sender as! CustomCell
        let detailView = segue.destinationViewController as! DetailViewController
        detailView.preContact = cell.contact

    }
}

}

我现在的问题是只有第一个搜索栏是固定的,当我输入它时它不会搜索。第二个搜索栏在滚动时消失。此外,当我单击一个名称时,它不再转到下一个视图。

【问题讨论】:

标签: ios swift uitableview uisearchbar


【解决方案1】:

问题是视图层次结构。

你的故事板是这样的:

在 TableView 上添加了搜索栏。

正确的层次结构是这样的:

您将 UITableViewController 更改为 UIViewController,并在注意视图层次结构的同时附加 SearchDisplayController。

它会起作用的:)

【讨论】:

  • Ryosuke Hiramastsu 好的,我已经很接近了。我的层次结构和你的一样,我将 UITableViewController 更改为 UIViewController,并使用 tableView.tableHeaderView = searchController.searchBar 来附加我的 searchController。页面顶部有一个搜索栏,表格视图中有一个搜索栏。第一个搜索栏是静止的,不会移动,但第二个搜索栏在滚动时移动。如果我尝试使用固定搜索栏进行搜索,它将不起作用。我该如何解决?我更新了我原来的帖子。请在 EDIT 1 下查看。
  • @2015HuntMJ 好的,你应该删除tableView.tableHeaderView = searchController.searchBar
  • @Ryousuke Hiramastsu 我删除了那行代码,第二个搜索栏不见了。固定搜索栏停留在页面顶部,但是当我尝试输入它时,它似乎没有连接到表格视图并且没有搜索。我删除的第二个搜索栏进行了搜索。
  • @2015HuntMJ 接下来,你从 故事板作为 IBOutlet 创建searchController。 u 将storyboars的searchDisplayController连接到代码,删除3行:var searchController:UISearchController!searchController.searchResultsUpdater = selfsearchController.dimsBackgroundDuringPresentation = false
  • @Ryousuke Hiramastsu 好吧,我从情节提要中创建了 searchController 作为出口并将其连接到代码。然后我删除了那三行代码。
【解决方案2】:

您正在添加一个UISearchController 作为您的UITableViewheaderView。表格视图标题不是“粘性的”,并且在用户滚动表格时与单元格一起滚动。考虑创建一个部分标题并将您的UISearchController 添加到viewForHeaderInSection

【讨论】:

    【解决方案3】:

    iOS9

    遇到同样的问题。我以编程方式添加了搜索栏。 这就是我修复我的方法。将来可能会有所帮助:)

    我在tableview 的viewForHeaderInSection 上添加了searchController.searchBar,而不是添加到tableView.tableHeaderView

    删除此行(如果存在)。 tableView.tableHeaderView = searchController.searchBar

    然后在 tableview 的委托上实现这个。

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return self.searchController.searchBar
    }
    
    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return searchController.searchBar.frame.height
    }
    

    希望对你有帮助!

    【讨论】:

    • 你好。在你的例子中,当我按下一个按钮(让我们说“d”)时,键盘会掉下来,我无法从搜索栏中按下“取消”......你知道为什么吗?
    【解决方案4】:

    我认为问题的出现是因为您已将搜索栏添加为表头视图。

    tableView.tableHeaderView = searchController.searchBar
    

    尝试像这样在 self.view 中添加搜索栏:

    self.view.addSubview("Your search bar")
    

    希望这能解决您的问题。

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 2017-07-22
      • 2017-03-24
      相关资源
      最近更新 更多