Swift - Segue on Dynamic TableCell - ios

I'm learning swift, and i'm having problems trying to fire a segue when a TableViewCell is touched, which is supposed to pass an url to a second view that for the moment just a displays it in a label.
i Dynamically create ( i've seen people use Programmatically, which is probably the right word) every single Cell, so, in the storyboard i don't have any object to link to another view except the view itself... and that's what i did.
So i connected the first view controller to the second, and added the code to perform the segue.
i'm not sure if it's right, my knowledge comes from tutorials that didn't exactly explain what i wanted to do.
down there there's the code of the two views.
first view
import UIKit
protocol sendInfoDelegate{
func userDidEnterInfo( WhichInfo info : String)
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var tableData = []
#IBOutlet weak var redditListTableView: UITableView!
var selectedCellURL : String?
var delegate : sendInfoDelegate? = nil
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// change the link to change the json source
getRedditJSON("http://www.reddit.com/.json")
}
//
//Creates a connection via a task (networktask) then parses the json
//
func getRedditJSON(whichReddit : String){
let mySession = NSURLSession.sharedSession()
let url: NSURL = NSURL(string: whichReddit)
let networkTask = mySession.dataTaskWithURL(url, completionHandler : {data, response, error -> Void in
var err: NSError?
var theJSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSMutableDictionary
let results : NSArray = theJSON["data"]!["children"] as NSArray
dispatch_async(dispatch_get_main_queue(), {
self.tableData = results
self.redditListTableView.reloadData()
})
})
networkTask.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//needs to be implemented
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
//creates the whole table
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
let redditEntry : NSMutableDictionary = self.tableData[indexPath.row] as NSMutableDictionary
cell.textLabel?.text = redditEntry["data"]!["title"] as? String
cell.detailTextLabel?.text = redditEntry["data"]!["author"] as? String
return cell
}
// action to be taken when a cell is selected
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let redditEntry : NSMutableDictionary = self.tableData[indexPath.row] as NSMutableDictionary
self.selectedCellURL = redditEntry["data"]!["url"] as? String
self.performSegueWithIdentifier("passInfo" , sender: indexPath)
println(self.selectedCellURL!)
if delegate != nil {
let information:String = self.selectedCellURL!
println("ciao")
delegate?.userDidEnterInfo(WhichInfo: information)
self.navigationController?.popViewControllerAnimated(true)
}
second view
import UIKit
class WebPageController : UIViewController, sendInfoDelegate {
var infoFromSVC: String?
#IBOutlet weak var labelVC: UILabel!
func userDidEnterInfo(WhichInfo info: String) {
self.infoFromSVC = info
labelVC.text = infoFromSVC
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "passInfo"{
let firstVController : ViewController = segue.destinationViewController as ViewController
firstVController.delegate = self
}
}
}
Thanks.

To pass any data to second view controller you need to implement prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) method in your first view controller and here pass any data to your second view controller through segue.destinationViewController object.
for example
// this method must be in first view controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "passInfo" {
var secondViewController : SecondViewController = segue.destinationViewController as SecondViewController
var indexPath = self.tableview.indexPathForSelectedRow() //get index of data for selected row
secondViewController.data = self.dataArray.objectAtIndex(indexPath.row) // get data by index and pass it to second view controller
}
}
The code for getting data in second view controller
override func viewDidLoad() {
super.viewDidLoad()
self.label.text = self.data
}
The data variable must be defined as a property of your second view controller.

Related

Preserve data in table from a View to another

I'm trying to send values from one view to other and print them in a table as an array. The program work and display the data but the problem is that when I try to add another value to the table when I return to the view that have the table the previous values are no longer there.
In this segment of code I sent the data to the other view
import UIKit
class NewContactoViewController: UIViewController, UITextFieldDelegate {
var contacto: String = ""
var numero: String = ""
#IBOutlet weak var contactoField: UITextField!
#IBOutlet weak var numField: UITextField!
let defaultValues = UserDefaults.standard
#IBAction func addButton(_ sender: UIButton) {
contacto = contactoField.text!
numero = numField.text!
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var secondController = segue.destination as! ContactosViewController
secondController.contactos = contactoField.text!
secondController.numerosmov = numField.text!
}
override func viewDidLoad() {
super.viewDidLoad()
self.contactoField.delegate = self
self.numField.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In this segment of code are the tableviews that display the data
import UIKit
class ContactosViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let defaultValues = UserDefaults.standard
var contactos: String = ""
var numerosmov: String = ""
var tablacontacto = [String] ()
var tablanumero = [String] ()
let cellIdentifier: String = "cell"
let cellIdentifier2: String = "cell2"
#IBOutlet weak var contactoTable: UITableView!
#IBOutlet weak var numTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton
// Do any additional setup after loading the view.
datosRecividos(contactos, numerosmov)
contactoTable.delegate = self
numTable.delegate = self
contactoTable.dataSource = self
numTable.dataSource = self
contactoTable!.reloadData()
numTable!.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
contactoTable.reloadData()
numTable.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func datosRecividos(_ contactosr: String, _ numerosr: String)
{
tablacontacto.append(contactosr)
tablanumero.append(numerosr)
let usercontacto = defaultValues.array(forKey: "contactoTable")
let usernumero = defaultValues.array(forKey: "numeroTable")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (tableView.tag == 1)
{
return(tablacontacto.count)
}
else if (tableView.tag == 2)
{
return(tablanumero.count)
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
if (tableView.tag == 1)
{
cell.textLabel?.text = tablacontacto[indexPath.row] as! String
}
else if (tableView.tag == 2)
{
cell.textLabel?.text = tablanumero[indexPath.row] as! String
}
return(cell)
}
}
There are several things wrong here, I would suggest reading again about tableView's (especially the "Load Initial Data" section) -
https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/CreateATableView.html
Your tables are getting data from the "tablacontacto" and "tablanumero" arrays.
There is no place in the code you sent to populate these arrays. (Do you see anything when these tables are on screen?)
Plus You are updating these arrays with only in the "func datosRecividos(_ contactosr: String, _ numerosr: String)" -
This method is only called once in the viewDidLoad and it is not called when you segue back to this screen
Plus you have no place you get data to your arrays from your userDefaults and there is no place you save the "new" data from "NewContactoViewController" to your userDefaults.
Make this two variables as static variables
internal static var CONTACTTO: String = ""
internal static var NUMERO: String = ""
then access this variables using,
NewContactoViewController.CONTACTTO
NewContactoViewController.NUMERO
Then there is no need sending this values using
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var secondController = segue.destination as! ContactosViewController
secondController.contactos = contactoField.text!
secondController.numerosmov = numField.text!
}
Or otherwise you can save these values in shared preferences
You can declare a delegate for data changing in NewContactoViewController
import UIKit
//Create a delegate for data changing
protocol ContactChageDelegate: class {
func contactChanged(newContact: String, newNumber: String)
}
class NewContactoViewController: UIViewController, UITextFieldDelegate {
//declare delegate variable
weak var contactChageDelegate: ContactChageDelegate?
...
#IBAction func addButton(_ sender: UIButton) {
contacto = contactoField.text!
numero = numField.text!
//if need notify data changing. maybe it will not change
//if data change {
self.contactChageDelegate.contactChanged(newContact: contacto, newNumber: numero)
//}
}
and use this delegate in ContactosViewController like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//let self to delegate
if let newContactoViewController = segue.destination as? NewContactoViewController {
newContactoViewController.contactChageDelegate = self
}
}
...
//implement delegate method
extension ContactosViewController: ContactChageDelegate {
internal func contactChanged(newContact: String, newNumber: String) {
//now you have new values
//change your data array
//and reload table
}
}

Passing CoreData keys to new ViewController

I am working on one part of my app which will function as a journal for the user, in which they can add an entry, then review or delete them afterwards. I followed a few Swift tutorials for CoreData and I have confirmed that the CoreData setup is working. However, I am having trouble getting values to pass to the UIViewController that will display the journal after already being saved. In one configuration I had tried it displayed no data, in another the data would stay the same no matter what entry selected, and in the setup below, this line journalEntryViewer.journalViewerTextView.text = journalTextToPass returns "found nil when unwrapping optional value."
Here is the code for the UITableViewController that acts as the list:
import UIKit
import CoreData
class JournalCollectionViewer: UITableViewController {
var JournalEntry = [NSManagedObject]()
var journalTextToPass:String!
var journalTitleToPass:String!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
self.tableView.reloadData()
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "JournalEntry")
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
JournalEntry = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
// MARK: - Table view data source
#IBOutlet weak internal var journalCollectionTable: UITableView!
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return JournalEntry.count
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("JournalCell")
let entry = JournalEntry[indexPath.row]
cell!.textLabel!.text =
entry.valueForKey("journalDate") as? String
return cell!
}
func selectedTableCell(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let entry = self.JournalEntry[indexPath.row]
self.performSegueWithIdentifier("ShowEntryViewer", sender: entry)
}
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowEntryViewer" {
let journalEntryViewer = segue.destinationViewController as! JournalEntryViewer
journalEntryViewer.self.navigationItem.title = journalTitleToPass
journalEntryViewer.journalViewerTextView.text = journalTextToPass
}
}
}
In the Swift file for the viewer (journalEntryViewer), all I have done is declared the class and the UITextView. Needless to say, I am at a loss. Any help appreciated!
When you assign value to the IBOutlet object in the prepareForSegue method that time it is not initialized, so you need to pass the string object and assign that string object to the journalViewerTextView in the viewDidLoadof JournalEntryViewer.
First declare two instance var in the JournalEntryViewer like this
var journalTitle: String?
var journalText: String?
Now use this var in viewDidload
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = journalTitle
self.journalViewerTextView.text = journalTitle
}
Now pass this journalTitle and journalText in the prepareForSegue method of JournalCollectionViewer
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowEntryViewer" {
let journalEntryViewer = segue.destinationViewController as! JournalEntryViewer
journalEntryViewer.journalTitle = journalTitleToPass
journalEntryViewer.journalText = journalTextToPass
}
}
New Edit:
Problem with your code is you have not used delegate method didSelectRowAtIndexPath instead of you are using something else selectedTableCell that is wrong try to implement delegate method of UITableView
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let entry = self.JournalEntry[indexPath.row]
self.performSegueWithIdentifier("ShowEntryViewer", sender: entry)
}
Now you are passing entry object so change your prepareForSegue like this
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowEntryViewer" {
let journalEntryViewer = segue.destinationViewController as! JournalEntryViewer
let entry = sender as! NSManagedObject
journalEntryViewer.journalTitle = entry.valueForKey("journalDate") as? String
journalEntryViewer.journalText = entry.valueForKey("journalEntryText") as? String
}
}

Swift: Pass UITableViewCell label to new ViewController ** CRASHING **

Have a UITableViewCell that passes data to a ViewController. Now it's crashing and I'm not sure why. Was working before then I started getting fata errors every time I tap one of the cells.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var signin: UITextField!
#IBOutlet weak var password: UITextField!
private let datetimes = ["02/25/16 5:47 PM", "02/25/16 2:47 PM", "02/21/16 5:33 AM"]
private let user = ["StevieE11", "Sikes911", "MaggieMae"]
private let feedback = ["The food was fucking terrible!", "Best food this side of the mason dixon line!", "If that waiter looks at me again I'm going to bite the shit out of him"]
var sendSelectedData = NSString()
override func viewWillAppear(animated: Bool) {
navigationItem.title = "Inbox"
//navigationController!.navigationBar.titleTextAttributes = [NSFontAttributeName: UIFont(name: "Helvetica Neue", size: 24)!]
}
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField.resignFirstResponder()
return true
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return user.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Create a new cell with the reuse identifier of our prototype cell
// as our custom table cell class
let cell = tableView.dequeueReusableCellWithIdentifier("myProtoCell") as! MyTableView
// Set the first row text label to the firstRowLabel data in our current array item
cell.user.text = user[indexPath.row]
// Set the second row text label to the secondRowLabel data in our current array item
cell.feedback.text = feedback[indexPath.row]
//cell.feedback.lineBreakMode = NSLineBreakMode.ByWordWrapping
//cell.feedback.numberOfLines = 2
// Set the datetime label to the datetime array
cell.dateTime.text = datetimes[indexPath.row]
// Return our new cell for display
return cell
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//println("You selected cell #\(indexPath.row)!")
// Get Cell Label text here and storing it to the variable
let indexPathVal: NSIndexPath = tableView.indexPathForSelectedRow!
//println("\(indexPathVal)")
let currentCell = tableView.cellForRowAtIndexPath(indexPathVal) as! MyTableView!;
//println("\(currentCell)")
//println("\(currentCell.iOSCellLbl?.text!)")
//Storing the data to a string from the selected cell
currentCell.user.text! = user[indexPath.row]
sendSelectedData = currentCell.user.text!
print(sendSelectedData)
//Now here I am performing the segue action after cell selection to the other view controller by using the segue Identifier Name
self.performSegueWithIdentifier("ShowFeedbackSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//Here i am checking the Segue and Saving the data to an array on the next view Controller also sending it to the next view COntroller
if segue.identifier == "ShowFeedbackSegue"{
//Creating an object of the second View controller
let controller = segue.destinationViewController as! FeedbackViewController
//Sending the data here
controller.SecondArray = sendSelectedData as String!
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Any thoughts?
Thanks
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier{
case "ShowFeedbackSegue":
if let controller = segue.destinationViewcontroller as? FeedbackViewController {
controller.SecondArray = sendSelectedData as String! // SecondArray must be of //type string
}
default: break
}
}
}

Swift 2 Nil Delegate

So I want to create a IOS application that generates a group of students, adds them to a course and then shows students. I can show students in a list in a table view but now I want to let the user touch a student's name and be taken to a page with information about that student (name highest grade etc). The student class is flawless, the course works and the only problem I have is that I can't get a student from one view to the other.
Here's what I have so far:
//
// DataTableViewController.swift
// assignment8
//
import Foundation
import UIKit
class DataTableViewController: UITableViewController {
var delegate:StudentSelectionDelegate! = nil
var students = [Student]();
var course = Course();
// MARK: - UITableViewDataSource
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func didSelectStudent(controller:UITableViewController, student:Student!) {
controller.navigationController?.popViewControllerAnimated(true)
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.course = courseStorage.getCourse();
self.students = course.getArrayOfStudentSortedByLastName();
return course.count;
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let row = indexPath.row
let currentStudent = students[row];
if (delegate != nil) {
delegate.didSelectStudent(self,student:currentStudent)
}
else {
print ("delegate is nil :(");
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("studentCell", forIndexPath: indexPath)
cell.textLabel?.text = students[indexPath.row].lastName + ", " +
students[indexPath.row].firstName;
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("ping");
if segue.identifier == "studentSegue" {
let nextScene = segue.destinationViewController as! studentViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow {
let selectedStudent = students[indexPath.row]
print (selectedStudent.firstName);
nextScene.student = selectedStudent;
}
}
}
}
and
//
// DataViewController.swift
// assignment8
//
import UIKit
class DataViewController: UIViewController {
#IBOutlet weak var dataLabel: UILabel!
var dataObject: String = ""
let tableData = ["One","Two","Three"];
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.dataLabel!.text = dataObject
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int)
-> Int {
return self.tableData.count;
}
}
and
//
// studentViewController.swift
// assignment8
//
import UIKit
protocol StudentSelectionDelegate {
func didSelectStudent(controller: UITableViewController, student:Student)
}
class studentViewController: UIViewController {
var delegate = StudentSelectionDelegate.self;
var name = String();
var student = Student();
#IBOutlet weak var StudentName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func didSelectStudent(controller:UITableViewController, student:Student!) {
student.description;
print ("pong")
StudentName.text = student.firstName + " " + student.lastName;
controller.navigationController?.popViewControllerAnimated(true);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// override func viewWillAppear(animated: Bool) {
// StudentName.text = name
// }
}
This is my storyboard so far.
So, any time I try clicking a student it will print the message that I've decided to use if the delegate is nil. So far I've tried looking at all the other answers on SO but none of them have fixed my issue.
To be able to send information from one view controller to another you should use segues. It seems like that's what you're doing according to the image. If you don't know how to use a segue, you can find a good answer here: Sending data with Segue with Swift
With segues you'll be able to set the delegate of the next view controller:
protocol MyDelegate {
func myFunction()
}
class FirstViewController: UIViewController, MyDelegate {
func myFunction() {
// do what the function does
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let secondVC = segue.destinationViewController as? SecondViewController {
secondVC.delegate = self
}
}
}
class SecondViewController: UIViewController {
var delegate: MyDelegate!
}
Before you segue to the second view controller (you're preparing for the segue), you set the delegate variable of SecondViewController to self, because FirstViewController conforms to MyDelegate protocol so it can be used there. Now, in SecondViewController you can use delegate.myFunction() and it will do whatever is written inside the FirstVC's function, because the FirstVC is SecondVC's delegate.

Segue from Custom Data Cell in Swift

I am new to Swift and IOS, I used to have a normal table view and everything worked. I have now implemented a Custom Table view cell and was wondering how to implement my PrepareForSegue method with my UITableView. I want to be able to send the selected Table Cell index to the segue for the next controller to access a certain array position. Right now the sender Object is a CustomCell: UITableViewCell object. can I access the table index from that object or some other way?
//
// ViewController.swift
// OBU Bus Tracker
//
// Created by AJ Norton on 4/20/15.
// Copyright (c) 2015 AJ Norton. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
#IBOutlet var table: UITableView!
var locations = [String]()
var overall = Dictionary<String, AnyObject>()
override func viewDidLoad() {
super.viewDidLoad()
// check if the user is running the app for the first time
// if let firstTime = NSUserDefaults.standardUserDefaults().objectForKey("firstTime")
// {
//
// println("second time")
// }
// else
// {
// println("worked")
// NSUserDefaults.standardUserDefaults().setBool(true, forKey: "firstTime")
// }
if let path = NSBundle.mainBundle().pathForResource("busSchedule", ofType: "plist")
{
if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject>
{
locations = dict.keys.array
overall = dict
}
}
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return locations.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: CustomRouteViewCell = table.dequeueReusableCellWithIdentifier("Cell") as! CustomRouteViewCell
cell.locationTitle.text = "\(locations[indexPath.row])"
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
println("I was clicked")
performSegueWithIdentifier("routeToTime", sender: indexPath.row)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//TODO
println("\(sender?.integerValue)")
if segue.identifier == "routeToTime"
{
var ttvc = segue.destinationViewController as! TimeViewController
var s = sender as! CustomRouteViewCell
println("\(s.in)")
var place = s.indentationLevel as! Int
var dicts = overall[locations[place]] as! Dictionary<String,AnyObject>
var arr = dicts["Weekday"] as! [Int]
ttvc.days = dicts
ttvc.times = arr.reverse()
}
}
}
performSegueWithIdentifier("routeToTime", sender: indexPath.row)
you call above method. so in this method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
the local argument sender is indexPath.row, is NOT a instance of CustomRouteViewCell.
So you can write code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "routeToTime"
{
var ttvc = segue.destinationViewController as! TimeViewController
var place = sender as! Int
var dicts = overall[locations[place]] as! Dictionary<String,AnyObject>
var arr = dicts["Weekday"] as! [Int]
ttvc.days = dicts
ttvc.times = arr.reverse()
}
}
It is best to write code in the MVC patten, so don't store your data in a tableview cell.
Whateve you want do that, you must set a cell's property(For example: rowIndex: Int) that indicate the indexRow of the data in this method 'func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)'. Your code looks like:
if segue.identifier == "routeToTime"
{
var ttvc = segue.destinationViewController as! TimeViewController
var cell = sender as! CustomRouteViewCell
var place = cell.indexRow
var dicts = overall[locations[place]] as! Dictionary<String,AnyObject>
var arr = dicts["Weekday"] as! [Int]
ttvc.days = dicts
ttvc.times = arr.reverse()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: CustomRouteViewCell = table.dequeueReusableCellWithIdentifier("Cell") as! CustomRouteViewCell
cell.locationTitle.text = "\(locations[indexPath.row])"
cell.indexRow = ... //Set the index of cell's data.
return cell
}
By the way, the indentationLevel property is:
var indentationLevel: Int // adjust content indent. default is 0
How about storing the cell index as a NSUserDefault and retrieving it from the other side?
That way you can use a generic segue created through the storyboard, implement the table cells on selected function.

Resources