如何防止搜索栏在滚动上消失? iOS Swift [英] How to prevent search bar from disappearing on scroll? iOS Swift
问题描述
我正在创建一个联系人应用。我的表格视图顶部有一个滚动条。
I am creating a contact app. I have a scroll bar at the top of my table view.
当我向下滚动搜索栏消失时。
When I scroll down the search bar disapears.
如何防止搜索栏在滚动条上消失?我希望它始终保持在页面顶部,如第一张图片。
How to prevent search bar from disappearing on scroll? I want it to stay at the top of the page at all times like in the first picture.
这是我的故事板的图片:
Here is a picture of my storyboard:
如果解决方案不在故事板中,这是我的视图控制器代码:
Here is my view controller code for if the solution is not in storyboard:
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的解决方案采取的步骤:
Here are the steps I have taken based off Ryosuke Hiramatsu's solution:
- 命令X表视图。
- 添加视图。
- 命令V表视图进入新视图。
- 在视图控制器中,将UITableViewController更改为UITableView
- 向视图控制器添加一个名为table view的插座。
- 删除表格视图函数中的覆盖。
- 删除以下代码行:tableView.tableHeaderView = searchController.searchBar
- 返回故事板并将搜索栏移出表格视图。它将出现在表格视图的后面。
- 向下移动表格视图并向上移动搜索栏。
- 添加必要的约束。
- Command X the table view.
- Add a view.
- Command V the table view into the new view.
- In the view controller, change UITableViewController to UITableView
- Add an outlet to the view controller named table view.
- Remove the overrides in the table view functions.
- Remove this line of code: tableView.tableHeaderView = searchController.searchBar
- Go back to storyboard and move the search bar out of the table view. It'll appear behind the table view.
- Move the table view down and the search bar up.
- Add necessary constraints.
我的视图现在看起来像这样:
My View now looks like this:
当我向下滚动时:
我的故事板:
最后我更新的视图控制器代码:
And finally My updated view controller code:
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
}
}
}
我现在的问题是,只有第一个搜索栏是固定的,当我输入时它不会搜索。滚动时第二个搜索栏消失。此外,当我点击一个名称时,它不再分段到下一个视图。
My Problem now is that only the first search bar is stationary and it doesn't search when I type in it. The second search bar disappears on scroll. Also when I click a name it no longer segues to the next view.
推荐答案
问题是视图层次结构。
你的故事板是这样的:
在TableView上添加了搜索栏。
Search Bar is added on TableView.
正确的层次结构如下:
您将UITableViewController更改为UIViewController,并附加SearchDisplayController,同时注意视图层次结构。
You change UITableViewController to UIViewController, and appending SearchDisplayController while being careful about view hierarcy.
它将起作用:)
这篇关于如何防止搜索栏在滚动上消失? iOS Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!