如何防止搜索栏在滚动时消失? iOS 斯威夫特
Posted
技术标签:
【中文标题】如何防止搜索栏在滚动时消失? iOS 斯威夫特【英文标题】:How to prevent search bar from disappearing on scroll? iOS Swift 【发布时间】: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 的解决方案采取的步骤:
-
Command X 表格视图。
添加视图。
Command V 将表格视图转换为新视图。
在视图控制器中,将 UITableViewController 更改为 UITableView
向视图控制器添加一个名为 table view 的 outlet。
删除表视图函数中的覆盖。
去掉这行代码:tableView.tableHeaderView = searchController.searchBar
返回故事板并将搜索栏移出表格视图。它会出现在表格视图的后面。
向下移动表格视图并向上移动搜索栏。
添加必要的约束。
我的视图现在看起来像这样:
当我向下滚动时:
我的故事板:
最后是我更新的视图控制器代码:
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
我现在的问题是只有第一个搜索栏是固定的,当我输入它时它不会搜索。第二个搜索栏在滚动时消失。此外,当我单击一个名称时,它不再转到下一个视图。
【问题讨论】:
这个问题可能重复:***.com/questions/24796274/… 【参考方案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 = self
,searchController.dimsBackgroundDuringPresentation = false
。
@Ryousuke Hiramastsu 好吧,我从情节提要中创建了 searchController 作为出口并将其连接到代码。然后我删除了那三行代码。【参考方案2】:
您正在添加一个UISearchController
作为您的UITableView
的headerView
。表格视图标题不是“粘性的”,并且在用户滚动表格时与单元格一起滚动。考虑创建一个部分标题并将您的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")
希望这能解决您的问题。
【讨论】:
以上是关于如何防止搜索栏在滚动时消失? iOS 斯威夫特的主要内容,如果未能解决你的问题,请参考以下文章
UISearchBar 不在 TableViewController 的表视图标题中?