Search Results segue to other View controller in swift - ios

I am implementing search controller programatically on navigation bar it is working fine and showing result, if I can select the tableview cell(did select method) segue is working fine . when I select the searched result it is not segue to next view controller. It is showing same view controller and tableview is reloading with data. I have show once click search result segue to next view controller
image
enter image description here
var modeldata = [ModelData]()
var FilerData = [ModelData]()
override func viewDidLoad() {
super.viewDidLoad()
self.searchcontroller = UISearchController(searchResultsController: nil)
self.searchcontroller.delegate = self
self.searchcontroller.searchBar.delegate = self
self.searchcontroller.hidesNavigationBarDuringPresentation = false
self.searchcontroller.dimsBackgroundDuringPresentation = true
self.navigationItem.titleView = searchcontroller.searchBar
self.definesPresentationContext = true
self.searchcontroller.searchResultsUpdater = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return modeldata.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
let row = indexPath.row
let values = modeldata[row] as ModelData
cell.NameLabel.text = values.name
return cell
}
func updateSearchResults(for searchController: UISearchController) {
let searchToSearch = searchController.searchBar.text
if(searchToSearch == "")
{
modeldata = self.FilerData
}
else{
modeldata.removeAll()
let itemsarray = self.FilerData
var ListArray = [String]()
for ListItems in itemsarray {
ListArray.append(ListItems.name!)
if(ListItems.name?.range(of: searchToSearch!, options: .caseInsensitive) != nil)
{
self.modeldata.append(ListItems)
}
}
}
self.TableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "next", sender:indexPath.row )
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let selectrow = sender as? Int
let name = modeldata[selectrow!].name
let nextview = segue.destination as? WekiViewController
nextview?.namestring = name!
}

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.

Search results are cut off when searching TableView

My search is working correctly except the display is not working as expected. When I am performing a search, the last search result is slightly cut off and the portion of the display is all gray. I would expect it to remain the same background color as the rows.. Any help would be appreciated.
EDIT:
import UIKit
import Foundation
// For search
extension MasterViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchText: searchController.searchBar.text!)
}
}
class MasterViewController: UITableViewController {
let searchController = UISearchController(searchResultsController: nil)
var filteredFighters = [Fighter]()
var detailViewController: DetailViewController? = nil
var objects = [Any]()
// Creates array of fighters
var fighterArray = [Fighter]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem
if let split = self.splitViewController {
let controllers = split.viewControllers
self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
// Access all the data from JSON
let JR = JSONReceiver()
fighterArray = JR.populateFighterJSONArray()
// Search related
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
navigationItem.title = "UFC Champions"
self.navigationController?.navigationBar.barTintColor = UIColor.black
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationController?.navigationBar.titleTextAttributes = [ NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont(name: "Arial", size: 26)!]
}
// FOr search
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredFighters = fighterArray.filter { fighter in
return fighter.name.lowercased().contains(searchText.lowercased())
}
tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/* DONT BELIEVE THIS IS NEEDED - DO NOT SEE IN PROFESSORS CODE
func insertNewObject(_ sender: Any) {
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
} */
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Determines which row was selected (e.g. which fighters, say element 1 points to fighter1)
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
// let stud = StudentsArray[indexPath.row]
let fighter: Fighter
if searchController.isActive && searchController.searchBar.text != "" {
fighter = filteredFighters[indexPath.row]
} else {
fighter = fighterArray[indexPath.row]
}
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
// Makes sure selected student points to the correct controller
controller.detailItem = fighter
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" {
return filteredFighters.count
}
return fighterArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let fighter: Fighter
if searchController.isActive && searchController.searchBar.text != "" {
fighter = filteredFighters[indexPath.row]
} else {
fighter = fighterArray[indexPath.row]
}
cell.textLabel!.text = fighter.name
cell.detailTextLabel?.text = fighter.record
cell.imageView?.image = UIImage(named: fighter.fighterImage)
self.tableView .sizeToFit()
// cell.detailTextLabel?.text = "fighterTest"
return cell
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return false
}
}

prepareForSegue sending the wrong (delayed) string extracted from array to second view controller

In VC1, I am trying to extract a string from an array, and send it to VC2. I do this in my prepareForSegue method. However, when I run it, there is a lag:
I tap row1(apples) in VC1 it goes to VC2 and shows apples in VC2
Tap back to VC 1
Tap row2(bananas), string passes as apples to
VC2
Tap back to VC1
I tap row3(oranges) in VC1 it goes to VC2
and shows bananas in VC2
etc etc.
Below is the code I am using. If anyone could help show me where I am going wrong, it would be much appreciated. Thank you..
class HomeSearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating, UISearchBarDelegate {
var filteredArray = [String]()
var shouldShowSearchResults = false
var searchController: UISearchController!
var databaseRef = FIRDatabase.database().reference()
var loggedInUser = AnyObject?()
var loggedInUserData = AnyObject?()
var productSearchArray = [AnyObject?]()
var productBrandArray = [String]()
var itemNameArray = [String]()
var picUrlArray = [String]()
var skuArray = [String]()
var nextScreenRow = Int()
var nextSceenRowNonSearch = Int()
var toPass = String()
var toPassSearch = String()
var initialSearchList = ["Apple", "Samsung", "Windows", "Google"]
#IBOutlet weak var tblSearchResults: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
loadListOfCountries()
configureSearchController()
tblSearchResults.delegate = self
tblSearchResults.dataSource = self
}
// MARK: Table Cells Stuff
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if shouldShowSearchResults {
return filteredArray.count
}
else {
return initialSearchList.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("homeSearchCell", forIndexPath: indexPath) as! HomeSearchTableViewCell
//note to self: need to pass on more than one variable for search
if shouldShowSearchResults {
cell.configure(filteredArray[indexPath.row], itemNameLabel: "text'", skuLabel: "TEXT")
//cell.textLabel?.text = filteredArray[indexPath.row]
}
else if shouldShowSearchResults == false{
cell.configureNISearch(initialSearchList[indexPath.row])
}
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 60.0
}
//to find out row and pass variable.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
//println("You selected cell #\(indexPath.row)!")spDetailSegue
if shouldShowSearchResults {
nextScreenRow = indexPath.row
// get to the next screen
self.performSegueWithIdentifier("spDetailSegue", sender: self)
}
else if shouldShowSearchResults == false{
nextSceenRowNonSearch = indexPath.row
// get to the next screen
self.performSegueWithIdentifier("searchSegue", sender: self)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "spDetailSegue") {
//Checking identifier is crucial as there might be multiple
// segues attached to same view
let detailVC = segue.destinationViewController as? pDetailViewController;
detailVC!.toPassSku = skuArray[nextScreenRow]
// print("vSku", )
}
if (segue.identifier == "searchSegue"){
//print("selected indexpath = ", selectedIndex)
let detailVC = segue.destinationViewController as? SearchDetailViewController;
detailVC!.toPassSearch = initialSearchList[nextSceenRowNonSearch]
}
}
//Search Bar stuff
func configureSearchController() {
// Initialize and perform a minimum configuration to the search controller.
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search here..."
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
//searchController.searchBar.scopeButtonTitles = ["Products", "Users"]
searchController.searchBar.barTintColor = UIColor.whiteColor()
searchController.searchBar.tintColor = UIColor.redColor()
// Place the search bar view to the tableview headerview.
tblSearchResults.tableHeaderView = searchController.searchBar
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
shouldShowSearchResults = true
tblSearchResults.reloadData()
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
shouldShowSearchResults = false
tblSearchResults.reloadData()
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
if !shouldShowSearchResults {
shouldShowSearchResults = true
tblSearchResults.reloadData()
}
searchController.searchBar.resignFirstResponder()
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchString = searchController.searchBar.text
// Filter the data array and get only those countries that match the search text.
filteredArray = itemNameArray.filter({ (item_name) -> Bool in
let countryText: NSString = item_name
return (countryText.rangeOfString(searchString!, options: NSStringCompareOptions.CaseInsensitiveSearch).location) != NSNotFound
})
// Reload the tableview.
tblSearchResults.reloadData()
}
}
once try by removing below line
tableView.deselectRowAtIndexPath(indexPath, animated: true)
from your didSelectRowAtIndexPath.
as #Lu_ suggested,
are you sure that didSelectRowAtIndexPath is called before prepareForSegue? you did not put your segue action from cell to controller?
This solved the issue. Thanks!

Go to another view controller table view cell xib

i have problem with segueing to view controller. I have table view with xib table view cell. Here is my code.
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
setupTableView()
setupDataSource()
}
private func setupTableView() {
tableView.backgroundColor = UIColor.clearColor()
tableView.allowsSelection = false
tableView.separatorColor = UIColor.clearColor()
tableView.registerNib(UINib(nibName: "ExampleTableViewCell", bundle: nil), forCellReuseIdentifier: "cell")
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ExampleTableViewCell
let list = pariwisata[indexPath.row]
cell.nameLabel.text = list.name
cell.typeLabel.text = list.type
let image = objects[indexPath.row]
cell.apply(image)
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("Row \(indexPath.row) selected")
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableView.bounds.width / 1.4
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
updateLocation(true)
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
updateLocation(false)
updateLocation(true)
}
func updateLocation(running: Bool) {
let mapView = self.view as! GMSMapView
let status = CLLocationManager.authorizationStatus()
if running {
if (CLAuthorizationStatus.AuthorizedWhenInUse == status) {
locationManager.startUpdatingLocation()
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
} else {
locationManager.stopUpdatingLocation()
mapView.settings.myLocationButton = false
mapView.myLocationEnabled = false
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "showTop10Detail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let destinationController = segue.destinationViewController as! DetailViewController
destinationController.detpariwisata = pariwisata[indexPath.row]
}
}
I have no errors when build the project, but I cant tap on my table view. I mean, I can tap on my table view, but it print nothing. What did I miss? pls give me clue. Thanks!
1) You have to delete:
tableView.allowsSelection = false
2) Use this line to pass from one cell to another page (DetailPage for example):
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("toDetailPage", sender: indexPath)
}
3) Use this method to pass data to a DetailPage:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath = self.tableView.indexPathForSelectedRow
let person = personList[indexPath!.row]
if segue.identifier == "toDetailPage"{
let DetailBookViewController = (segue.destinationViewController as! DetailPage)
DetailBookViewController.user_name = user_name
DetailBookViewController.user_age = user_age
DetailBookViewController.user_urlPicture = user_urlPicture
}
4) Remember:
In your storyboard you have to link your tableViewController with your DetailPage
You have to declare a class for Person and declare:
var PersonList = [Person]()
You have to declare your var in tableView class and in DetailPage class
Remove this line of code:
tableView.allowsSelection = false
It is not allowing the selection of cell.

found nil while trying to segue away from a tableView

I'm getting errors whenever I try to reference the viewTable in the viewDidLoad AFTER I click on a cell to transition with the segue. Thanks a lot!!
Basically I can't use the segue unless I comment out the tableview references in view did load... but I need those in order to use the search bar and im sure it will cause problems on the way back...
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView! {
didSet {
print("tableView is set")
}
}
let searchController = UISearchController(searchResultsController: nil)
let textCellIdentifier = "TextCell"
var buildings: [(String,String)] = []
var filteredBuildings = [(String,String)]()
var goToIndex: Int?
override func viewDidLoad() {
super.viewDidLoad()
print(tableView)
var buildingTuples = loadBuildings()
for tuple in buildingTuples {
self.buildings.append(tuple)
}
self.goToIndex = -1
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView!.tableHeaderView = searchController.searchBar
}
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredBuildings = buildings.filter { building in
return building.0.lowercaseString.containsString(searchText.lowercaseString)
}
self.tableView.reloadData()
}
// MARK: UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return self.buildings.count
if searchController.active && searchController.searchBar.text != "" {
return filteredBuildings.count
}
return buildings.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
/*
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let row = indexPath.row
cell.textLabel?.text = buildings[row].0
return cell
*/
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let tuple: (String, String)
if searchController.active && searchController.searchBar.text != "" {
tuple = filteredBuildings[indexPath.row]
} else {
tuple = buildings[indexPath.row]
}
cell.textLabel?.text = tuple.0
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
self.goToIndex = indexPath.row
self.performSegueWithIdentifier("MainToLocation", sender: self)
//print(buildings[row].0)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "MainToLocation" {
let locationViewController = (segue.destinationViewController as! LocationViewController)
locationViewController.building = self.buildings[self.goToIndex!]
}
}
extension ViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
You can try this..
let destinationVC = self.storyboard!.instantiateViewControllerWithIdentifier("viewController") as! NextViewController
var alreadyPushed = false
if let vc = self.navigationController?.viewControllers {
for viewController in vc {
if let viewController = viewController as? NextViewController {
self.navigationController?.popToViewController(viewController, animated: true)
print("Push your controller")
alreadyPushed = true
break
}
}
}
if alreadyPushed == false {
self.navigationController?.pushViewController(destinationVC, animated: true)
}

Resources