Searching TableView can't select row - ios

While searching a tableView, every time I try to select a row it just takes me back to the unsearched tableView. What am I missing? the segue works perfectly when not filtering through the table. The ability to select a row just disapears while the searchBar is activated.
import UIKit
import Foundation
class BenchmarkWODViewController: UITableViewController, UISearchResultsUpdating {
var WodList = [WOD]()
var FilteredWodList = [WOD]()
var Keyword = ""
var searchController : UISearchController?
var index = Int()
#IBAction func backButton(sender: AnyObject) {
self.navigationController?.popViewControllerAnimated(true)
}
override func viewDidLoad() {
super.viewDidLoad()
for wodData in BenchmarkWODs.library {
let wod = WOD(dictionary: wodData)
WodList.append(wod)
}
// Search Bar
self.searchController = UISearchController(searchResultsController: nil)
self.searchController?.searchBar.autocapitalizationType = .None
self.tableView.tableHeaderView = self.searchController?.searchBar
self.searchController?.searchResultsUpdater = self
self.Keyword = ""
definesPresentationContext = true
self.filterByName()
}
func filterByName(){
self.FilteredWodList = self.WodList.filter({ (wod: WOD) -> Bool in
if self.Keyword.characters.count == 0 {
return true
}
if (wod.name?.lowercaseString.rangeOfString(self.Keyword.lowercaseString)) != nil {
return true
}
return false
})
self.tableView.reloadData()
}
// Search Bar Function
func updateSearchResultsForSearchController(searchController: UISearchController) {
Keyword = searchController.searchBar.text!
self.filterByName()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.FilteredWodList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("BenchmarkCell", forIndexPath: indexPath) as UITableViewCell
let wod = self.FilteredWodList[indexPath.row]
if let wodName = wod.name {
cell.textLabel?.text = wodName
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.filterByName()
self.performSegueWithIdentifier("showBenchmarkDetail", sender: nil)
}
}

Figured it out after playing around. Apparently adding the below code corrects the problem.
searchController?.dimsBackgroundDuringPresentation = false

swift 'dimsBackgroundDuringPresentation' was deprecated in iOS 12.0 Use the obscuresBackgroundDuringPresentation property instead.
searchController?.obscuresBackgroundDuringPresentation = false

searchController.obscureBAckgroundDuringPresentation = false is deprecated in IOS 12.0, so for me it was issue with other gesture detector added to the tableview , so make sure you dont have any other gesture detector and touchesview method that distort the normal working flow of tablview's delegate method( didSelectAtRow ), hope it will work,

Related

Swift xcode IOS, return to tableview after selecting a search result

I am trying to create a joke app. The search bar works. But when I select the search results, it won't take me to the tableview( the jokes). How can I fix it? Thanks everyone in advance.
import UIKit
class JokeTableViewController: UITableViewController, UISearchResultsUpdating {
var jokes = [ "chiken", "Walk into A Bar", "Olives", "Racer", "love"]
var filteredJokes = [String]()
var searchController : UISearchController!
var resultsController = UITableViewController()
override func viewDidLoad() {
super.viewDidLoad()
self.resultsController.tableView.dataSource = self
self.resultsController.tableView.delegate = self
self.searchController = UISearchController(searchResultsController: self.resultsController)
self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.searchResultsUpdater = self
//self.searchController.dimsBackgroundDuringPresentation = false
}
func updateSearchResults(for searchController: UISearchController) {
self.filteredJokes = self.jokes.filter { (jokee:String) -> Bool in
if jokee.lowercased().contains(self.searchController.searchBar.text!.lowercased()){
return true
}else {
return false
}
}
//Update the results TableView
self.resultsController.tableView.reloadData()
}
//WHEN SELECTED TO TO THE JOKES
// HOW MANY?
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.tableView{
return self.jokes.count
} else {
return self.filteredJokes.count
}
}
//WHAT GOES INSIDE?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if tableView == self.tableView{
cell.textLabel?.text = self.jokes[indexPath.row]
} else{
cell.textLabel?.text = self.filteredJokes[indexPath.row]
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let selectedJoke = jokes[indexPath.row]
performSegue(withIdentifier: "moveToJokeDefinition", sender: selectedJoke)
}
override func prepare( for segue: UIStoryboardSegue, sender: Any?){
if let jokeVC = segue.destination as? JokeDefinitionViewController{
if let selectedJoke = sender as? String {
jokeVC.joke = selectedJoke
}
//select the jokes
}
}
}
You should use one global variable.
var globaldata = String
self.globaldata = self.jokes .... initData............
you should use this data in tableView Delegate functions.

Using searchController to filter tableView, but the tableView isn't updating

I have a UITableViewController that is displaying the titles of Tags I created. When I first navigate to the UITableViewController, it displays the Array of Tags just fine, but when I use the UISearchController to filter through Tags, the Array I created to store the filtered results updates and holds the correct data, but the TableView doesn't change. here are the two functions that are most likely causing the problem, but just in case, I will have the entire class (not long) down below.
numberOfRowsInSection:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchController.searchBar.text != "") {
return filteredTags.count
}
return Tags.count
}
cellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tagcell", for: indexPath) as! TagCell
var text = ""
if (searchController.searchBar.text != ""){
text = filteredTags[indexPath.row].title
} else {
text = Tags[indexPath.row].title
}
cell.cellLabel.text = text
return cell
}
Whole Class:
class TagCell: UITableViewCell{
#IBOutlet weak var cellLabel: UILabel!
}
class TagTableVC: UITableViewController{
//Table Content
var Tags: [Tag] = [globTS.animals, globTS.civilrights, globTS.guncontrol, globTS.gunrights, globTS.LGBTQ, globTS.prochoice, globTS.prolife]
var filteredTags = [Tag]()
//Searchbar Initialization
let searchController = UISearchController(searchResultsController: nil)
//Required Functions
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchController.searchBar.text != "") {
return filteredTags.count
}
return Tags.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tagcell", for: indexPath) as! TagCell
var text = ""
if (searchController.searchBar.text != ""){
text = filteredTags[indexPath.row].title
} else {
text = Tags[indexPath.row].title
}
cell.cellLabel.text = text
return cell
}
//Filters Tags array into Filtered array based on search query
func filterContentForSearchText(searchText: String, scope: String = "All"){
filteredTags = Tags.filter{ $0.title.lowercased().contains(searchText.lowercased())}
}
}
extension TagTableVC: UISearchResultsUpdating {
//calls the filter function everytime the searchbar is activated
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchText: searchController.searchBar.text!)
}
}
After reevaluating the filteredTags, you should call reloadData on your tableview
func filterContentForSearchText(searchText: String, scope: String = "All"){
filteredTags = Tags.filter{ $0.title.lowercased().contains(searchText.lowercased())}
self.tableView.reloadData()
}

How to implement search bar like this?

I would like to add a search bar above my collection view and when press it will show like the video showing .https://www.youtube.com/watch?v=mgS2Pzy5eJk .Thanks.
You can directly use iOS default UISearchDisplayController as following tutorial:
UISearchDisplayController Tutorial
Read this tutorial and try it..
Hope it helps...
When the user click the searchBar:
remove or hide the NavigationBar
Adjust the auto layout constraint of search Bar accordingly.
Add animation as you want
Do these thing in func searchBarTextShouldBeginEditing(searchBar: UISearchBar)
func searchBarTextShouldBeginEditing(searchBar: UISearchBar) {
//remove or hide the NavigationBar
//update auto layout constraint
UIView.animateWithduration(0.3) {
self.view.layoutIfNeeded()
}
return true
}
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdating {
#IBOutlet weak var tableview: UITableView!
let unfilteredNFLTeams = ["Bengals", "Ravens", "Browns", "Steelers", "Bears", "Lions", "Packers", "Vikings",
"Texans", "Colts", "Jaguars", "Titans", "Falcons", "Panthers", "Saints", "Buccaneers",
"Bills", "Dolphins", "Patriots", "Jets", "Cowboys", "Giants", "Eagles", "Redskins",
"Broncos", "Chiefs", "Raiders", "Chargers", "Cardinals", "Rams", "49ers", "Seahawks"].sorted()
var filteredNFLTeams: [String]?
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
filteredNFLTeams = unfilteredNFLTeams
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
tableview.tableHeaderView = searchController.searchBar
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let nflTeams = filteredNFLTeams else {
return 0
}
return nflTeams.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "nandhu", for: indexPath)
if let nflTeams = filteredNFLTeams {
let team = nflTeams[indexPath.row]
cell.textLabel!.text = team
}
return cell
}
func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text, !searchText.isEmpty {
filteredNFLTeams = unfilteredNFLTeams.filter { team in
return team.lowercased().contains(searchText.lowercased())
}
} else {
filteredNFLTeams = unfilteredNFLTeams
}
tableview.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

UISearchController causes black screen Swift 2.0

I have a strange problem in iOS 9 with Swift 2.0. I added UISearchController in my tableViewController but it causes a strange black screen problem. When I press the search bar and write something it shows my filtered results without any problem but when I tap another tab bar button like Bookmarks and after that when I tap tableViewController which is Most Viewed again it shows black screen like screen shot.
There is my tableViewController;
import UIKit
class CitiesTableViewController: UITableViewController, UISearchResultsUpdating {
// MARK: - Class Properties
private var cities = [String]()
private var veterinaries = [Veterinary]()
private var filteredVeterinaries = [Veterinary]()
private var resultSearchController: UISearchController!
// MARK: - TableViewController Life Cycle Methods
override func viewDidLoad() {
super.viewDidLoad()
self.getCitiesList()
self.configureResultsSearchController()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
self.resultSearchController.active = false
}
// MARK: - Configuring Search Bar Controller
private func configureResultsSearchController() {
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.hidesNavigationBarDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.resultSearchController.searchBar.placeholder = "Klinik veya ilçe adı"
self.tableView.tableHeaderView = self.resultSearchController.searchBar
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 }
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.resultSearchController.active { return self.filteredVeterinaries.count }
else { return self.cities.count }
}
// MARK: - Table view Delegate Methods
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (self.resultSearchController.active) {
self.performSegueWithIdentifier(Constants.ShowDetailViewControllerSegueIdentifier, sender: nil)
} else {
self.performSegueWithIdentifier(Constants.ShowTownsTableViewControllerSegueIdentifier, sender: nil)
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Constants.CellIdentifier, forIndexPath: indexPath)
if (self.resultSearchController.active) {
cell.textLabel?.text = self.filteredVeterinaries[indexPath.row].name
cell.detailTextLabel?.text = self.filteredVeterinaries[indexPath.row].address
return cell
} else {
cell.textLabel?.text = self.cities[indexPath.row]
return cell
}
}
// MARK: - PARSE Query Methods
private func getCitiesList() {
let parseQueries = ParseQueries()
parseQueries.downloadListData() {
(let parseResults) in
if let veterinaries = parseResults as? [Veterinary] {
self.veterinaries = veterinaries
for vet in veterinaries {
if let city = vet.city {
self.cities.append(city)
}
}
dispatch_async(dispatch_get_main_queue()) {
self.cities = HelperMethods().removeDuplicatesAndSort(array: self.cities)
self.tableView.reloadData()
}
}
}
}
// MARK: - UISearchController Delegate Methods
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.filteredVeterinaries.removeAll(keepCapacity: false)
if let searchBarText = searchController.searchBar.text{
let searchText = searchBarText.lowercaseString
// Searching with Veterinary Name and Veterinary City
self.filteredVeterinaries = self.veterinaries.filter({$0.name?.lowercaseString.rangeOfString(searchText) != nil})
self.filteredVeterinaries += self.veterinaries.filter({$0.town?.lowercaseString.rangeOfString(searchText) != nil})
tableView.reloadData()
}
}
This is the black screen image from iOS 9 simulator same as real device.
I think its deiniting my tableView when I tap the searchBar and it can't init again. Is this a bug or something ?
How can I solve this problem ?
Thank you !
Friend, in your viewDidLoad() insert this code line:
self.definesPresentationContext = true
See how I put (line 29):
click here to see
I recently faced the same issue and I could fix it easily.
self.definesPresentationContext = true was already defined in viewDidLoad() but it didn't solve this issue.
In the above question, maybe you show CitiesTableViewController directly when you tap MostViewed tabbar item.
In order to avoid the black screen, you can embed CitiesTableViewController in a UINavigationController and try to show the navigationcontroller when tapping the tabbar item.
This solution will avoid the black screen issue.

headerview from previous view takes up space in UISearchController search results

I have a simple tableView, DailyAttendanceController, with a searchbar. Searchbar was added in its viewDidLoad. View TableView here.
import UIKit
class OldCellsTableViewController: UITableViewController {
let data = ["A", "B", "C"]
var searchController:UISearchController!
let resultsController = SearchResultsUpdater()
override func viewDidLoad() {
super.viewDidLoad()
resultsController.data = data
searchController = UISearchController(searchResultsController: resultsController)
let searchBar = self.searchController.searchBar
searchBar.scopeButtonTitles = ["All", "Short", "Long"]
searchBar.placeholder = "Search for a student"
searchBar.sizeToFit()
self.tableView.tableHeaderView = searchBar
self.searchController.searchResultsUpdater = resultsController
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let info = data[indexPath.row]
cell.textLabel?.text = info
return cell
}
}
I then created another class, SearchResultsController, to handle the search. Searching works fine, but space is allocated for DailyAttendanceController's header. View SearchResultsController here
How do I remove this?
Code for my SearchResultsController:
import UIKit
import CoreData
class SearchResultsController: UITableViewController, UISearchResultsUpdating {
var data:[String] = []
var filteredData:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filteredData.removeAll(keepCapacity: true)
let searchString = searchController.searchBar.text
for info in data {
if (info.uppercaseString.rangeOfString(searchString.uppercaseString) != nil) {
filteredData.append(info)
}
}
tableView.reloadData()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = filteredData[indexPath.row]
return cell
}
}

Resources