我正在创建一个联系人应用。我在表格视图的顶部有一个滚动条。
当我向下滚动搜索栏消失时。
如何防止搜索栏在滚动条上消失?我希望它始终保持在页面顶部,就像第一张图片一样。
这是我的故事板的图片:
如果解决方案不在故事板中,那么这是我的视图控制器代码:
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的解决方案采取的步骤:
我的视图现在看起来像这样:
当我向下滚动时:
我的故事板:
最后我更新了视图控制器代码:
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
}
}
}
我现在的问题是,只有第一个搜索栏是固定的,当我输入时它不会搜索。滚动时第二个搜索栏消失。此外,当我点击一个名称时,它不再会转到下一个视图。
答案 0 :(得分:5)
问题是视图层次结构。
你的故事板是这样的:
在TableView上添加了搜索栏。
正确的等级是这样的:
您将UITableViewController更改为UIViewController,并附加SearchDisplayController,同时注意视图层次结构。
它会起作用:))
答案 1 :(得分:1)
遇到同样的问题。我以编程方式添加了搜索栏。 这是我如何修复我的。未来可能会有所帮助:)
我在tableview&#39; 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
}
希望它有所帮助!
答案 2 :(得分:0)
我认为问题出现是因为您已将搜索栏添加为表标题视图。
tableView.tableHeaderView = searchController.searchBar
尝试在self.view中添加搜索栏,如下所示:
self.view.addSubview("Your search bar")
希望这能解决您的问题。
答案 3 :(得分:0)
您正在添加UISearchController
UITableView
headerView
。表视图标题不是&#34; sticky&#34;,并在用户滚动表格时滚动单元格。考虑创建一个标题标题,并在UISearchController
中添加viewForHeaderInSection
。