Getting error in handling the selected row in table in iOS swift - ios

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("SearchTableViewCellIdentifier") as! SearchTableViewCell
var item = self.searchResult[indexPath.row] as? PFObject
cell.post = item
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndex rowIndex: Int)
{
let indexPath = tableView.indexPathForSelectedRow()
let currentCell = tableView.cellForRowAtIndexPath(indexPath!)! as UITableViewCell
println(currentCell.textLabel!.text)
}
I am not getting the actual value. I am getting nil on printing currentCell.textLabel!.text

just remove override
class yourclassName: UIViewController, UITableViewDataSource, UITableViewDelegate
var cod: AnyObject?
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}
func tableView(tableView: UITableView, didSelectRowAtIndex rowIndex: Int)
{
//Handle row selection
// choice 1
let indexPath = tableView.indexPathForSelectedRow();
// if it is not work follow second option
cod = self.searchResult[indexPath.row] as? PFObject
// choice 2
cod = self.searchResult[rowIndex] as? PFObject
println(cod)
self.performSegueWithIdentifier("yourSegueName", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "yourSegueName") {
var svc = segue!.destinationViewController as secondViewController;
svc.toPass = cod
}
}
in your second VC create this string
var toPass:String!

Related

Pass Data (Label) from TableViewCell to another ViewController

I want to pass the Label from a TableViewCell to a ViewController when I click on the Cell. In the end it should be like twitter, that if you click on a cell with a Label you get passed on a detailViewController with the same Label init.
My Code doesn't work as I just get the blanket Label from the Storyboard...
import UIKit
import Firebase
class JobTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var valueToPass:String!
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
// Arvice return to count jobs
return jobs.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
let valueToPass = currentCell.textLabel?.text
print("value: \(valueToPass)")
performSegue(withIdentifier: "toDetails", sender: valueToPass)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "JobCell", for: indexPath) as! JobTableViewCell
let job = jobs[indexPath.row]
cell.job = job
//spacing
cell.contentView.backgroundColor = UIColor.clear
let whiteRoundedView : UIView = UIView(frame: CGRect(x: 10, y: 8, width: self.view.frame.size.width - 20, height: 120))
whiteRoundedView.layer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [0.36, 0.39, 0.40, 1.0])
whiteRoundedView.layer.masksToBounds = false
whiteRoundedView.layer.cornerRadius = 2.0
whiteRoundedView.layer.shadowOffset = CGSize(width: 0, height: 0)
whiteRoundedView.layer.shadowOpacity = 0.0
cell.contentView.addSubview(whiteRoundedView)
cell.contentView.sendSubview(toBack: whiteRoundedView)
cell.emojiLabel.text = cell.emojiString
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetails" {
let destinationViewController = segue.destination as! JobDetailViewController
destinationViewController.valueToPass = (sender as? String)!
}
}
My Cell:
import UIKit
import Firebase
class JobTableViewCell: UITableViewCell {
#IBOutlet weak var jobLabel: UILabel!
var job: Job! {
didSet {
jobLabel.text = job.text
}
}
}
Job.Swift:
import Foundation
import Firebase
class Job{
var text: String = ""
let ref: DatabaseReference!
init(text: String) {
self.text = text
ref = Database.database().reference().child("jobs").childByAutoId()
}
init(snapshot: DataSnapshot)
{
ref = snapshot.ref
if let value = snapshot.value as? [String : Any] {
text = value["text"] as! String
}
}
func save() {
ref.setValue(toDictionary())
}
func toDictionary() -> [String : Any]
{
return [
"text" : text,
]
}
}
And in my DestinationController:
import UIKit
import Firebase
class JobDetailViewController: UIViewController {
#IBOutlet weak var jobDetail: RoundText!
var valueToPass: String = ""
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
jobDetail.text = valueToPass
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Jobinformation"
}
}
You should not be using cells to store data. You should have a data model that represents the data you are showing in the cells, and you should use the indexPath of the selected cell to look up the data in your data model.
Quick solution:
Change
performSegue(withIdentifier: "yourSegueIdentifer", sender: self) to performSegue(withIdentifier: "yourSegueIdentifer", sender: valueToPass)
2.Your prepare for Segue method should looks like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourSegueIdentifer" {
let destinationViewController = segue.destination as! AnotherViewController
destinationViewController.valueToPass = sender as? String
}
}
On AnotherViewController create var valuteToPass: String = "" and set your label.text = valueToPass
But I think you should not use currentCell.textLabel.text value, instead use the original value. (like if you set your currentCell as cell.textLabel.cell = array[indexPath.row], your valueToPass should be valueToPass = array[indexPath.row])
EDIT:
You use didDeselectRowAt method, instead of didSelectRowAt.
Change func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) to
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
Don't use global variable, create it in didSelectRowAt.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
let valueToPass = currentCell.textLabel?.text
print("value: \(valuteToPass)")
performSegue(withIdentifier: "toDetails", sender: valueToPass)
}
On DestinationController:
class DestinationController: UIViewController {
var valuteToPass: String = ""
override func viewDidLoad() {
super.viewDidLoad()
jobLabel.text = valueToPass
}
}
EDIT2
JobTableViewController
delete var valueToPass:String!
Change let valueToPass = jobs[indexPath.row].text instead of let valueToPass = currentCell.textLabel?.text
I checked this change in your code, this will work.
Hi I cant comment but im using #Dris answer and I kept getting this error that says
Could not cast value of type 'UITableViewCell' (0x115464e18) to 'NSString' (0x10fa594c8).
The SIGABRT targets the line destinationViewController.valueToPass = (sender as? String)!
Why is that?
this is basically my code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Determine what to do when a cell in a particular section is selected.
print("did select: \(indexPath.row) ")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow!
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
valueToPass = currentCell.textLabel?.text
print("valueToPass: \(String(describing: valueToPass))")
performSegue(withIdentifier: "cellToView", sender: self)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if tableView == self.tableView {
let currentNotif = notificationList[indexPath.row]
cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell?.textLabel?.text = currentNotif.notifType
cell?.detailTextLabel?.text = "\(currentNotif.notifTime) \n\(currentNotif.notifContent)"
}
if tableView == self.tableViewAnnounce {
let currentAnnounce = announcementList[indexPath.row]
cell = tableView.dequeueReusableCell(withIdentifier: "cellAnn", for: indexPath) as UITableViewCell
cell?.textLabel?.text = currentAnnounce.annouceType
cell?.detailTextLabel?.text = "\(currentAnnounce.annouceTime) \n\(currentAnnounce.annouceContent)"
}
return cell!
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "cellToView" {
// perform custom segue operation.
let destinationViewController = segue.destination as! ExtendedAnnouncementViewController
destinationViewController.valueToPass = (sender as? String)!
}
}
I'd avoid using a global variable to pass the data to the destination view controller. Defer the lookup until you are ready to pass the data.
And, avoid using force unwrap, it leads to runtime crashes.
Use something like this instead:
let segueIdentifier = "yourSegueIdentifer"
let labelDataSource: [String] = ["SomeText"]
func label(forIndexPath indexPath: IndexPath) -> String? {
let index = indexPath.row
guard labelDataSource.indices.contains(index) else { return nil }
return labelDataSource[index]
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: segueIdentifier, sender: indexPath)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard segue.identifier == segueIdentifier,
let indexPath = sender as? IndexPath,
let destinationViewController = segue.destination as? AnotherViewController else { return }
destinationViewController.valuePassed = label(forIndexPath: indexPath)
}

Passing coredata from tableview to another tableview

I am struggling with getting my care data to populate my second tableview controller. The data is populating the first tableview and I can select a row and the segue is used to go to the second table but the labels are not populated.
I've looked all over and have found older samples or obj-c but I cannot figure it out, so any help pointing this n00b in the right direction will be helpful.
Here is what I have, I think I am missing how to populate a variable to pass in prepareForSegue in the list tableview, but I could be wrong. I get a warning error in that function (Warning cannot assign value of type 'ListEntity' to type '[ListEntity]').
CoreData
Entity = ListEntity
Attributes = title, event & location (all as Strings)
listTableViewController
import UIKit
import CoreData
class ListTableViewController: UITableViewController {
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var lists = [ListEntity]()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "The List"
let addButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: #selector(ListTableViewController.addButtonMethod))
navigationItem.rightBarButtonItem = addButton
}
func addButtonMethod() {
print("Perform action")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
reloadData()
tableView.reloadData()
}
func reloadData() {
let fetchRequest = NSFetchRequest(entityName: "ListEntity")
do {
if let results = try managedObjectContext.executeFetchRequest(fetchRequest) as? [ListEntity] {
lists = results
}
} catch {
fatalError("There was an error fetching the list!")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lists.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ListCell") as! ListTableViewCell
let list = lists[indexPath.row]
cell.configurationWithSetup(list)
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("DetailsSegue", sender: self)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "DetailsSegue" {
let destinationVC = segue.destinationViewController as! DetailsTableViewController
let indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow!
print(indexPath.row) // Print the Row selected to console
// Place the code to pass data here?
// destinationVC.lists = lists[indexPath.row]
// Warning cannot assign value of type 'ListEntity' to type '[ListEntity]'
}
}
}
listTableViewCell
import UIKit
class ListTableViewCell: UITableViewCell {
#IBOutlet weak var titleLabel: UILabel!
func configurationWithSetup(list: AnyObject) {
titleLabel.text = list.valueForKey("title") as! String?
}
}
detailsTableViewController
import UIKit
import CoreData
class DetailsTableViewController: UITableViewController {
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var lists = [ListEntity]()
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DataCell") as! DetailsTableViewCell
let list = lists[indexPath.row]
cell.configurationWithSetup(list)
return cell
}
}
detailsTableViewCell
import UIKit
import CoreData
class DetailsTableViewCell: UITableViewCell {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var eventLabel: UILabel!
#IBOutlet weak var locationLabel: UILabel!
func configurationWithSetup(list: AnyObject) {
titleLabel.text = list.valueForKey("title") as! String?
eventLabel.text = list.valueForKey("event") as! String?
locationLabel.text = list.valueForKey("location") as! String?
}
}
The warning contains the answer - just change
var lists = [ListEntity]() to
var lists = ListEntity(), or var lists:ListEntity! and when you prepare for segue set that value.
Then you will need to change
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DataCell") as! DetailsTableViewCell
// as data source is not array you can just you the item you passed
// let list = lists[indexPath.row]
cell.configurationWithSetup(lists)
return cell
}
You should use a static table view if you just want one cell
More info per you current issue
class DetailsTableViewController: UITableViewController {
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var theDetailListEntity:ListEntity!
override func viewDidLoad() {
super.viewDidLoad()
print(theDetailListEntity) // check that you passed it across
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DataCell") as! DetailsTableViewCell
cell.configurationWithSetup(theDetailListEntity)
return cell
}
}
Don't forget to add prepare for segue in the listTableViewController otherwise theDetailListEntity won't be set... and then it will crash.
Depending on how you set up your segue, it may differ. But this is what you need
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("showMyDetailView", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showMyDetailView" {
guard let
vc = segue.destinationViewController as? DetailsTableViewController,
ip = sender as? NSIndexPath else { fatalError() }
let item = lists[ip.row]
vc.theDetailListEntity = item
// set the item in the next VC
tableView.deselectRowAtIndexPath(ip, animated: true)
}
}

how to pass the value from table view cell to view controller

I have one table view with many cell.Each cell have one image and one label.And what i need is when ever user press any cell it have to go to detail viewcontroller.And there i need to show the respective image and label name in my detail view controller.How to do that.
I have done all segue.But in my detail view controller i have one image and label.Now how can i show the image and label name - when i select the any cell from my table view ??
import UIKit
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet var tableView: UITableView!
var valueToPass:String!
var selectedIndexPath: NSIndexPath = NSIndexPath()
var tableData: [String] = ["Christ Redeemer", "Great Wall of China", "Machu Picchu","Petra","Pyramid at Chichén Itzá","Roman Colosseum","Taj Mahal"]
var arrImageName: [String] = ["ChristRedeemer", "GreatWallOfChina", "MachuPicchu","Petra","PyramidChichenItza","RomanColosseum","TajMahal"]
var tableRate: [String] = ["$120", "$100", "$222","$1000","$500","$900","$2000"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func numberOfSectionsInTableView(tableView: UITableView) ->Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:CustomTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell") as! CustomTableViewCell
cell.imageVW.image = UIImage(named:self.arrImageName[indexPath.row])
cell.lblName.text = self.tableData[indexPath.row]
cell.rateName.text = self.tableRate[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedIndexPath = indexPath
performSegueWithIdentifier("DetailView", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let indexPath = self.selectedIndexPath
if (segue.identifier == "DetailView") {
var viewController = segue.destinationViewController as! DetailVC
viewController.data = UIImagePNGRepresentation(UIImage(named:self.arrImageName[indexPath.row])!)!
//viewController.name = self.tableData[[indexPath.row]]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is my detailvc.swift
import UIKit
class DetailVC: UIViewController {
var data: NSData = NSData()
var name: String = String()
#IBOutlet weak var ImgView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.ImgView.image = UIImage(data: data)
//self.detailLabelNamee.text = name
}
}
change your did select with something like this
Declare one gloabal indexPath in ViewContrller like this
var selectedIndexPath: NSIndexPath = NSIndexPath()
Change your didselect like this
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedIndexPath = indexPath
self.performSegueWithIdentifier("DetailView", sender: self)
}
Now in prepareForSegue method add this
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let indexPath = self.selectedIndexPath
if (segue.identifier == "DetailView") {
var viewController = segue.destinationViewController as! DetailVC
viewController.data = UIImagePNGRepresentation(UIImage(named:self.arrImageName[indexPath.row]))
viewController.name = self.tableData[indexPath.row]
}
}
Now add two global identifier in DetailVC like below
var data: NSData = NSData()
var name: String = String()
Now assign this data and string to imageview and label in viewdid load
change the viewdidload of detailVC like this
override func viewDidLoad() {
super.viewDidLoad()
self.ImgView.image = UIImage(data: data)
self.detailLabelNamee.text = name
}
Hop this will help.
In your didSelectRowAtIndexPath you can just perform the segue and in prepareForSegue you can get the indexPath with self.tableView.indexPathForSelectedRow. And of course it returns an optional and you have to check it first for safety. I think this is the easiest way.
In your didSelectRowAtIndexPath you can get the index path of the selected row and then you can performSegue and pass index path in sender.
In prepareForSeque , from the index path , you can get the image , tableData and tableRate . Which you can pass to detail view . Something like below
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("DetailView", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let selectedIndexPath = sender as! NSIndexPath
if (segue.identifier == "DetailView") {
var viewController = segue.destinationViewController as! DetailVC
viewController . setValues(tableData:tableData[selectedIndexPath] , rate: tableRate[selectedIndexPath] , imageName:arrImageName[selectedIndexPath])
}
class DetailVC: UIViewController {
var imageName:String!
var tableData:String!
var tableRate:String!
func setValues(tableData:String , rate:String , imageName:String){
imageName = tableData
tableRate = rate
imageName = imageName
}
or
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let selectedIndexPath = sender as! NSIndexPath
if (segue.identifier == "DetailView") {
var viewController = segue.destinationViewController as! DetailVC
viewController.imageName = self.arrImageName[selectedIndexPath.row]
viewController.tableData = self.tableData[selectedIndexPath.row]
viewController.tableRate = self.tableRate[selectedIndexPath.row]
}
You can declare a variable for store indexpath in that .
var selectedItemIndex = Int()
on click of cell write below lines in didselectowatndexaPath
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedItemIndex = indexPath.row
self .performSegueWithIdentifier(“YourViewController”, sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let yourVC = segue.destinationViewController as! YourViewController
yourVC.text = tableData[selectedItemIndex]
yourVC.image = UIImage(named:arrImageName[selectedItemIndex])
}
You are almost there! The line:
performSegueWithIdentifier("DetailView", sender: self)
needs changing. 'self' is passing a reference of the current view controller to the prepareForSegue method. If you change 'self' to 'indexPath', then prepareForSegue will see the cell index path in the 'sender' object and you take what you want from that.
You could do something like:
if (segue.identifier == "yourSegueIdentifer") {
var viewController = segue.destinationViewController as! DetailVC
let indexPath = sender as! NSIndexPath
viewController.passedImageName = self.arrImageName[indexPath.row]
viewController.passedData = self.tableData[indexPath.row]
viewController.passedRate = self.tableRate[indexPath.row]
and in DetailVC:
class DetailVC: UIViewController {
var passedImageName:String!
var passedData:String!
var passedRate:String!

UISearchController for TableView

This is what my Table View looks like. Each cell Strings a text from a .txt
Search Filter works fine. But When I select one of the results e.g. "How" it prints the the Content of "Hello" instead.
I'm thinking this is probably because "Hello" is programmed as the first String so it will always be the result of the first cell when clicked. I am needing help with figuring out how the search results are linked to it's own content. if that makes any sense?
Here's the code below. The code reads from .txt file swell as search the text file. the results when clicked on do not match.
import UIKit
class title_ViewController: UITableViewController, UISearchResultsUpdating {
var SongTitle = [String]()
var SongLyrics = [LText]()
var filteredSongs = [String]()
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
if let path = NSBundle.mainBundle().pathForResource("DataBase", ofType: "txt"){
do {
let stringFromFile = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)
var Title: [String] = stringFromFile.componentsSeparatedByString("#")
Title.removeAtIndex(0)
//Seperates the Title from the Lyrics
var t1 = Array(Title[0].componentsSeparatedByString("^"))
t1.removeAtIndex(0)
SongTitle = Title
SongLyrics = [LText(LyricsText: t1)]
}catch{
print(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.resultSearchController.active{
return self.filteredSongs.count
}else{
return self.SongTitle.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let Cell: AnyObject = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
Cell.textLabel?!.text = SongTitle[indexPath.row]
if self.resultSearchController.active{
Cell.textLabel?!.text = self.filteredSongs[indexPath.row]
}else{
Cell.textLabel?!.text = self.SongTitle[indexPath.row]
}
return Cell as! UITableViewCell
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.filteredSongs.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c]%#", searchController.searchBar.text!)
let array = (self.SongTitle as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredSongs = array as! [String]
self.tableView.reloadData()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
let DestViewController = segue.destinationViewController as! ViewController
DestViewController.LyricString = SongTitle[indexPath.row]
}
}
any help is welcomed, thanks in advance.
The problem lies in your prepareForSegue. You need to amend it to test whether the searchController is active. If so, you should use filteredSongs to determine which song to pass to the destination VC, rather than SongTitle:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
let DestViewController = segue.destinationViewController as! ViewController
if self.resultSearchController.active {
DestViewController.LyricString = self.filteredSongs[indexPath.row]
}else{
DestViewController.LyricString = self.SongTitle[indexPath.row]
}
}
(As an aside, it is convention that variable names should start with a lowercase letter - songTitle not SongTitle, etc.)
You can perform segue manually in didSelectRowAtIndexPath by searching position of selected String from array, then you can get correct position -
Example -
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let Cell: AnyObject = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let str: String= Cell.textLabel.text
// now find str in array and then get position
int pos = getPositionOfStringInArray(str)
// now perform segue for pos
//code...
}

Passing data from table view to textview of view controller

I just found a tutorial how to pass data between two table views to textview of ViewController, its nice but I need an app about passing data from just one table view to textview of ViewController, I'm searching about this little problem but can't find it, hope you guys understand me, here is a pic of app tutorial I founded, I uploaded in tiny pic because can't post it here:
import UIKit
class FirstTableViewController: UITableViewController{
var FirstTableArray = [String]()
var SecondArray = [SecondTable]()
var ThirdArray = [ThirdView]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
FirstTableArray = ["First", "Second", "Third","Fourth"]
SecondArray =
[SecondTable(SecondTitle: ["jdhfhjd","kldjjlkdfjd"]),
SecondTable(SecondTitle: ["FirstSecond","SecondSecond","ThirdSecond"]),
SecondTable(SecondTitle: ["FirstThird","SecondThird","ThirdThird"]),
SecondTable(SecondTitle: ["FirstFourth"])]
ThirdArray = [ThirdView(ThirdViewArray: [lf1,lf2]),
ThirdView(ThirdViewArray: ["asdkljf","asdfasd","asdfas"]),
ThirdView(ThirdViewArray: ["asdkljf","asdfasd","asdfas"]),
ThirdView(ThirdViewArray: ["asdkljf"])]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FirstTableArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var Cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
Cell.textLabel?.text = FirstTableArray[indexPath.row]
return Cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow()!
var DestViewController = segue.destinationViewController as! SecondTableViewController
var SecondTableArrayTwo : SecondTable
SecondTableArrayTwo = SecondArray[indexPath.row]
DestViewController.SecondArray = SecondTableArrayTwo.SecondTitle
var ThirdAnswerArray : ThirdView
ThirdAnswerArray = ThirdArray[indexPath.row]
DestViewController.SecondAnswerArray = ThirdAnswerArray.ThirdViewArray
}
}
Here is your complete Updated code for one tableView to detailView:
import UIKit
class FirstTableViewController: UITableViewController{
var FirstTableArray = [String]()
var passThisArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// This array will display on your tableviewcell.
FirstTableArray = ["First", "Second", "Third","Fourth"]
//You can pass element of this array
passThisArray = ["element1", "element2", "element3", "element4"]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FirstTableArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var Cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
Cell.textLabel?.text = passThisArray[indexPath.row]
return Cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detailView") {
var vc = segue.destinationViewController as! ViewController
//Get the Index of selected Cell
var indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow()!
//assign string to next view controller instance from selected cell.
vc.FirstString = FirstTableArray[indexPath.row]
}
}
}
And you have to modify many things from your project.
And HERE is your project.

Resources