如何防止搜索栏在滚动时消失? iOS Swift
How to prevent search bar from disappearing on scroll? iOS Swift
我正在创建一个联系人应用程序。我的 table 视图顶部有一个滚动条。
当我向下滚动时,搜索栏消失了。
如何防止搜索栏在滚动时消失?我希望它像第一张图片一样始终位于页面顶部。
这是我的故事板的图片:
如果解决方案不在情节提要中,这是我的视图控制器代码:
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() { [=12=].name < .name }
//remove contacts whose locations are nil
contacts = contacts.filter() { [=12=].location != "nil"}
//remove contacts whose titles phone email and department are all nil
contacts = contacts.filter() {
if([=12=].title != "" || [=12=].phone != "" || [=12=].email != "" || [=12=].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 的解决方案采取的步骤:
- 命令 X table 视图。
- 添加视图。
- 命令V table视图进入新视图。
- 在视图控制器中,将 UITableViewController 更改为 UITableView
- 向名为 table 视图的视图控制器添加一个出口。
- 删除 table 视图函数中的覆盖。
- 删除这行代码:tableView.tableHeaderView = searchController.searchBar
- 返回故事板并将搜索栏移出 table 视图。它会出现在 table 视图后面。
- 向下移动 table 视图,向上移动搜索栏。
- 添加必要的约束条件。
我的视图现在看起来像这样:
当我向下滚动时:
我的故事板:
最后是我更新的视图控制器代码:
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() { [=13=].name < .name }
//remove contacts whose locations are nil
contacts = contacts.filter() { [=13=].location != "nil"}
//remove contacts whose titles phone email and department are all nil
contacts = contacts.filter() {
if([=13=].title != "" || [=13=].phone != "" || [=13=].email != "" || [=13=].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
}
}
}
我现在的问题是只有第一个搜索栏是静止的,当我输入时它不搜索。第二个搜索栏在滚动时消失。此外,当我单击一个名称时,它不再转到下一个视图。
问题是视图层次结构。
你的故事板是这样的:
在 TableView 上添加了搜索栏。
正确的层次结构是这样的:
您将 UITableViewController 更改为 UIViewController,并附加 SearchDisplayController,同时注意视图层次结构。
它会起作用:)
我认为出现问题是因为您将搜索栏添加为 table header 视图。
tableView.tableHeaderView = searchController.searchBar
尝试在 self.view 中添加搜索栏,如下所示:
self.view.addSubview("Your search bar")
希望这能解决您的问题。
您正在添加 UISearchController
作为 UITableView
的 headerView
。 Table 视图 header 不是 "sticky",并且当用户滚动浏览 table 时与单元格一起滚动。考虑创建一个部分 header 并在 viewForHeaderInSection
.
中添加您的 UISearchController
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
}
希望对您有所帮助!
我正在创建一个联系人应用程序。我的 table 视图顶部有一个滚动条。
当我向下滚动时,搜索栏消失了。
如何防止搜索栏在滚动时消失?我希望它像第一张图片一样始终位于页面顶部。
这是我的故事板的图片:
如果解决方案不在情节提要中,这是我的视图控制器代码:
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() { [=12=].name < .name }
//remove contacts whose locations are nil
contacts = contacts.filter() { [=12=].location != "nil"}
//remove contacts whose titles phone email and department are all nil
contacts = contacts.filter() {
if([=12=].title != "" || [=12=].phone != "" || [=12=].email != "" || [=12=].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 的解决方案采取的步骤:
- 命令 X table 视图。
- 添加视图。
- 命令V table视图进入新视图。
- 在视图控制器中,将 UITableViewController 更改为 UITableView
- 向名为 table 视图的视图控制器添加一个出口。
- 删除 table 视图函数中的覆盖。
- 删除这行代码:tableView.tableHeaderView = searchController.searchBar
- 返回故事板并将搜索栏移出 table 视图。它会出现在 table 视图后面。
- 向下移动 table 视图,向上移动搜索栏。
- 添加必要的约束条件。
我的视图现在看起来像这样:
当我向下滚动时:
我的故事板:
最后是我更新的视图控制器代码:
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() { [=13=].name < .name }
//remove contacts whose locations are nil
contacts = contacts.filter() { [=13=].location != "nil"}
//remove contacts whose titles phone email and department are all nil
contacts = contacts.filter() {
if([=13=].title != "" || [=13=].phone != "" || [=13=].email != "" || [=13=].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
}
}
}
我现在的问题是只有第一个搜索栏是静止的,当我输入时它不搜索。第二个搜索栏在滚动时消失。此外,当我单击一个名称时,它不再转到下一个视图。
问题是视图层次结构。
你的故事板是这样的:
在 TableView 上添加了搜索栏。
正确的层次结构是这样的:
您将 UITableViewController 更改为 UIViewController,并附加 SearchDisplayController,同时注意视图层次结构。
它会起作用:)
我认为出现问题是因为您将搜索栏添加为 table header 视图。
tableView.tableHeaderView = searchController.searchBar
尝试在 self.view 中添加搜索栏,如下所示:
self.view.addSubview("Your search bar")
希望这能解决您的问题。
您正在添加 UISearchController
作为 UITableView
的 headerView
。 Table 视图 header 不是 "sticky",并且当用户滚动浏览 table 时与单元格一起滚动。考虑创建一个部分 header 并在 viewForHeaderInSection
.
UISearchController
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
}
希望对您有所帮助!