Selections from List and reload Tableview Swift - ios

I am quite new to this. I am getting an issue with selection items and post back to tableview on specific index cell (reload).
Scenario: I have two view controllers and both contains tableview.
FirstViewController: I am already displaying data from webservice into Tableview but on different action types I have used didSelectRow function which shows to ListViewController for item selection. In FirstViewController main model is Unit.
ListViewController: Simple list of data displaying in tableView for selection.
Issue: is how can I select item from ListViewController and pass data to FirstViewController tableview that change occurs on specific cell and then I have to post values with updated values. How can I reload tableview or model?
Model:
struct Unit : Codable {
let sectionList : [SectionList]?
}
struct SectionList : Codable {
let title : String?
let items : [Item]?
}
struct Item : Codable {
let actionType : Int?
let textField : String?
let textValue : String?
let pickList: [SectionList]?
let multiSelect: Bool?
let selectedValue: [String]?
let version: Int?
let masterId: Int?
let itemValue: String?
}
Updated FirstController:
class FirstViewController: UIViewControlller, ListDelegate {
var selectedIndex: Int?
var selectedSection: Int?
//Click event for navigation from FirstViewController to SecondViewController
#IBAction func BackButtonAction(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
func listFunc(listValue: String) {
AppData?.sectionList?[selectedSection!].items?[selectedIndex!].textField = listValue
tableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Add these two line in your code
selectedIndex = indexPath.row
selectedSection = indexPath.section
}
}
Updated : ListViewController:
protocol ListDelegate {
func listFunc(listValue: String)
}
class SecondViewController: UIViewControlller {
var delegate: ListDelegate?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!)!
//print(currentCell.textLabel?.text as Any)
currentCell.accessoryType = .checkmark
delegate?.listFunc(listValue: currentCell.textLabel?.text ?? "")
self.navigationController?.popViewController(animated: true)
}
}

You've got a handful of options to accomplish this. Assuming that the selected value is the only value that you've got to pass, using closures would be the easiest thing you could do.
1) Declare a closure that holds a type of your need inside ListViewController:
`var didSelectItem : ((YourType, IndexPath) -> ())?`
2) In ListViewController's didSelectRow method, use the closure:
`self.didSelectItem?(yourDataSourceItemAtIndexpath, indexPath)`
3) You'll get a callback for the triggered closure when you use this closure from your ListViewController instance inside FirstViewController like:
let myListInstance = ListViewController()
myListInstance.didSelectItem = { selectedItem, selectedIndex in
//You'll get the selected item inside this block, do model updation here
}
After updating your model with new values, if you want to reload your tableView only at the particular(updated) index, you can use:
self.yourTableView.reloadSections(sections: IndexSet, with: UITableView.RowAnimation) to reload a whole section or..
self.yourTableView.reloadRows(at: [IndexPath], with: UITableView.RowAnimation) to reload a row in a section
(If you're performing multiple updates simultaneously, keep in mind that you'll have to do these reloads inside self.yourTableView.beginUpdates() and self.yourTableView.endUpdates())
NOTE:
You'll have to handle your dataSource properly during these reloads to make sure you have the right number of rows or sections before and after the reload, adding/subtracting the rows/sections that you insert/delete. Else, your app will crash!
If you don't want to risk that, just reload the whole table with yourTableView.reloadData()
Also keep in mind that there are other ways to pass data across controllers and this is just a suggestion based on what I assume your use case to be

I hardly able to understand your code, it's totally messed up according to me.
I found that most of your code is done and I am adding rest your things that you need to do.
In your FirstViewController.swift, didSelectRowAt func,
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
vc.Indexdata = // your data that you wanted to show in your next controller,
// if variable is different then assign data to that var
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
In ViewController.swift, didSelectRowAt func,
// Comment these below lines
// let vc = self.storyboard?.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
// self.navigationController?.pushViewController(vc, animated: true)
// Add below line
self.navigationController?.popViewController(animated: true)
Now check it should work.

Related

How to pass data from View Controller to Container View in swift

This is my screens ....
I want to pass data from Offline View Controller to InstantVC. I don't know how to do that 🤔.
Basically, I have segmented Controller. When user tab Instant it show the segmented view controller and hide the Schedule view controller. And pass data according to selected segmented.
Here is the Offline View controller to pass data
switch response.result {
case .success:
if let result = response.data {
do {
let resultIs = try JSONDecoder().decode(GetActiveOrderModel.self, from:result)
print("Massage: \(resultIs.state)")
if let results = resultIs.orderData{
let storyboard = UIStoryboard(name: "Rider", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "instantVC") as! InstantVC
print(" Order ID is \(results.orderId)")
vc.arryOfOrder.append(results.orderId!)
//navigationController?.pushViewController(vc, animated: true)
}
} catch {
print(error)
}
}
case .failure(let error):
print(error)
}
And here is Instant view controller that restive data from Offline VC
var arryOfOrder = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
print("---------->>>>>>>>> \(arryOfOrder)")
}
// MARK: - Custom Functions
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arryOfOrder.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! CellForInstantVC
cell.orderNum.text = "\(arryOfOrder[indexPath.row])"
return cell
}
func addOrderNumber(orderNumber : Int){
arryOfOrder.append(orderNumber)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
You can use prepare Segue to access Container controller and save its reference
class Master: UIViewController, ContainerToMaster {
#IBOutlet var containerView: UIView!
var containerViewController: Container?
#IBOutlet var labelMaster: UILabel!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "containerViewSegue" {
containerViewController = segue.destinationViewController as? Container
}
}
And then you can use containerViewController to pass data
containerViewController?.arryOfOrder = ArrayOfOrder
or you can have function in container ... pass ArrayOfOrder to that function .. which will also reload tableView
containerViewController?.updateData(dataArray: ArrayOfOrder)
If you want to pass data from parent to child on an action that happened in the parent class, you can access the children of the current UIViewController using
children.forEach { (viewController) in
if let temp = viewController as? InstantVC{
temp.property = dataToPass
}
}
The above will only work if both your view controllers are kept as children to the parent at all times and are never removed. If you remove them as children and re-add them at a later stage you will need to maintain references to the child and update that reference since the children array wont have that UIViewController. But since you are using storyboards, this should work fine.
If you want to access data from on action on the children class, you can access the parent view controller using:
let dataToUse = (parent as? OfflineVC).someProperty

How can i add cell to UITableView Section with core data saved info

I have a UITableView whit 3 sections, i have 3 tables for each section, i use 3 popUps to fill the tables(Formula, Time, Step) for each section at this point everything works fine
var sections : [String] = []
var buttons : [Int] = []
sections = [" Formula:", " Time:", " Steps: "]
buttons = [1,2,3]
var formula : [Formula] = []
var time : [Time] = []
var step : [Step] = []
var fetchReultFormula : NSFetchedResultsController<Formula>!
var fetchResultTime : NSFetchedResultsController<Time>!
var fetchResultStep : NSFetchedResultsController<Step>!
On tableView section of code:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return formula.count
case 1:
return time.count
default:
return step.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell :UITableViewCell = UITableViewCell(style: .subtitle, reuseIdentifier: "mycell")
switch (indexPath.section) {
case 0:
let result = formula[indexPath.row]
cell.textLabel?.text = result.ing
cell.detailTextLabel?.text = "\(result.cant) grs"
cell.imageView?.image = UIImage(named: result.type!)
case 1:
let result = [indexPath.row]
cell.textLabel?.text = result.name
cell.detailTextLabel?.text = "\(resultado.min) min"
cell.imageView?.image = UIImage(named: "time")
default:
let result = step[indexPath.row]
cell.textLabel?.text = result.desc
cell.detailTextLabel?.text = ""
cell.imageView?.image = UIImage(named: "check")
}
return cell
}
When i add record to any table trough popUpView how can i add this record to respective section when dismiss the popUpView?
As a result of our comments, lets go with delegation to see if we can solve your problem:
Declare a protocol, you can do it in another file or in your ViewController:
This protocol has a method to fetch data again after you add data in FormulaViewController
protocol DataFetcherDelegate {
func fetchData()
}
class ViewController: UIViewController {
Then conform to this protocol from your ViewController:
class ViewController: UIViewController, DataFetcherDelegate {
After you conform to the protocol, you are gonna have to implement fetchData method inside ViewController, this is where you are gonna put core data fetch request to get up to date data:
func fetchData() {
print("fetchingData")
// write your data fetching code here, then make your arrays equal respectively again.
// once fetching and assigning data to arrays are complete do:
tableView.reloadData()
}
Now go to FormulaViewController and add a delegate variable like following:
class FormulaViewController: UIViewController {
var delegate: DataFetcherDelegate?
Go back to ViewController then, where ever you are instantiating your FormulaViewController (I obtained the code below from your comment, you need to cast the VC as FormulaViewController as well, it is a bit updated don't use your old code) and assign ViewController as the delegate of FormulaViewController:
let vc = storyboard!.instantiateViewController(withIdentifier: "formulaView") as! FormulaViewController
vc.delegate = self // assigning self as delegate of FormulaVC
self.present(vc, animated: true, completion: nil)
Now we are done with ViewController part, we will go to FormulaViewController now and do the following:
Before you dismiss your popupView after saving new data successfully, now we are gonna tell our delegate (ViewController) to fetch core data again then we will dismiss FormulaViewController:
//save your respective item to your core data, formula, time or step
// then for the sake of example, lets add a Formula:
let newFormula = Formula(/*with your core data context*/)
//save to your core data with context. like persistentContainer.viewContext.save(), I dont know how you implemented that.
delegate?.fetchData()
dismiss(animated: true, completion: nil)
Now hopefully once the FormulaViewController is dismissed, the data of ViewController will be updated as well.

Passing Data Forward In Swift Without Segue

I'm currently making a to do list app using Swift 4. The home view controller has a tableview with some categories in it and when one is selected, it takes the user to a view controller where the items in that category are listed. I have a bug however as only the most recent item is showing in the list.
I think this is due to the way I am navigating to the list view controller. I am currently doing this:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let destinationVC = ListVC()
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedCategory = categoryArray[indexPath.row]
}
navigationController?.pushViewController(destinationVC, animated: true)
tableView.deselectRow(at: indexPath, animated: true)
}
And in the list view controller, I just have this to load the data:
var selectedCategory : Category? {
didSet {
loadItems()
}
}
I firstly created this app using storyboards and when using segues, it worked completely fine.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! TodoListVC
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedCategory = categoryArray[indexPath.row]
}
}
So basically, the problem is that in the secondary list view controller, it will only show the most recently added item and no other ones even when they are stored in core data. I think it is to do with the way I am showing the secondary view controller as I am creating a new object every time.
How to properly go to the next view controller?
Remove the segue and add the storyboard id
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "storyboard_id") as! TodoListVC
vc.selectedCategory = categoryArray[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
Try this it will help you:-
You can send data from one view controller to another using storyboard
instance.
let next = self.storyboard?.instantiateViewController(withIdentifier: "NextControllerStoryBoard_id")as! NextController
next.str = "data which you want to pass"
self.navigationController?.pushViewController(next, animated: true)
here NextController is your controller class name where you want to go.str is the string name which you declare on NextController like
let str = String()
you are able to send string in that variable in same way you send any thing array dictionary ,image, Int value etc.
NextControllerStoryBoard_id is id which you declare at storyboard of that controller
In storybard id add your storybard id
Hope this will help you
I think that with this chunk of code I already sensed that you are passing data to the other view controller the incorrect way:
let destinationVC = ListVC()
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedCategory = categoryArray[indexPath.row]
}
...
What I would suggest is that, instead of passing the data this way, you have to pass an array containing the items within the selected category using an array, then pass that array via the prepare for segue.
Then from the viewdidappear or viewdidload method in the receiving view controller, use the passed array from the source VC and use that as a datasource for your table view within that 2nd VC.

Segue using didSelectRowAtIndexPath

I have a Master-Detail VC setup for a Core Data project. If the searchBar is active, one set of results is displayed, if it's not active, the objects from the fetchedResultsController displays in the MasterVC.
I had been trying to segue using prepareForSegue, but I my instructor suggested I use didSelectRowAtIndexPath to do the segue.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedNote: Note
// Check to see which table view cell was selected.
if tableView == self.tableView {
selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Note // <--this is "everything"
} else {
// need this to unwrap the optional
if let filteredObjects = filteredObjects {
selectedNote = filteredObjects[indexPath.row]
}
}
// Set up the detail view controller to show.
let detailViewController = DetailViewController()
detailViewController.detailDescriptionLabel = selectedNote.valueForKey("noteBody") as! UILabel
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
// original code
navigationController?.pushViewController(detailViewController, animated: true)
}
I'm getting this compiler error:
Variable 'selectedNote' used before being initialized--it's declared at the top of the method!
If I add "self" before selectedNote like so:
detailViewController.detailDescriptionLabel = self.selectedNote.valueForKey("noteBody") as! UILabel
'MasterViewController' does not have a member named 'selectedNote' despite being there. So I'm obviously mucking up something.
I put a breakpoint in before let detailViewController = DetailViewController() and in lldb it's printing out the right object. I've looked around here for a solution, but I'm coming up short. I can't find applicable code that works on GitHub.
class Note: NSManagedObject {
#NSManaged var dateCreated: NSDate
#NSManaged var dateEdited: NSDate
#NSManaged var noteTitle: String
#NSManaged var noteBody: String
}
Any ideas how to pass the selectedNote's properties forward to the detailViewController?
Update:
Based on the responses I've gotten, I've shut up the compiler warnings with this code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedNote: Note?
// Check to see which table view cell was selected.
if tableView == self.tableView {
selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Note // <--this is "everything"
} else {
// need this to unwrap the optional
if let filteredObjects = filteredObjects {
selectedNote = filteredObjects[indexPath.row]
}
}
// Set up the detail view controller to show.
let detailViewController = DetailViewController()
detailViewController.detailDescriptionLabel.text = (selectedNote!.valueForKey("noteBody") as! String)
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
// original code
navigationController?.pushViewController(detailViewController, animated: true)
}
But I'm getting this in the console when it crashes:
There are already notes in the app
fatal error: unexpectedly found nil while unwrapping an Optional value
However, when I type po selectedObject the object I clicked displays in the console.
You need to declare selectedNote as optional like this:
var selectedNote: Note?
And later check if value exist before using it.
if let note = selectedNote {
// Set up the detail view controller to show.
let detailViewController = DetailViewController()
detailViewController.detailDescriptionLabel = note.valueForKey("noteBody") as! UILabel
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
// original code
navigationController?.pushViewController(detailViewController, animated: true)
}
Update:
The problem is that you are trying to create DetailViewController
let detailViewController = DetailViewController()
But what you need instead is to have reference to the DetailViewController in order to pass information to it.
So you can create segue from Master to Detail controller in Interface builder. Then remove logic from didSelectRowAtIndexPath
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
}
And implement it in prepareForSegue method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let cell = sender as? UITableViewCell {
let indexPath = tableView.indexPathForCell(cell)!
var selectedNote: Note?
if filteredObjects?.count > 0 {
selectedNote = filteredObjects![indexPath.row]
}else {
selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Note // <--this is "everything"
}
if let note = selectedNote {
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = note
}
}
}
}
showDetail - segue identifier which you need to setup in IB.
var detailItem: AnyObject? - you need to declare it in DetailViewController.

Swift: Pass UITableViewCell label to new ViewController

I have a UITableView that populates Cells with data based on a JSON call. like so:
var items = ["Loading..."]
var indexValue = 0
// Here is SwiftyJSON code //
for (index, item) in enumerate(json) {
var indvItem = json[index]["Brand"]["Name"].stringValue
self.items.insert(indvItem, atIndex: indexValue)
indexValue++
}
self.tableView.reloadData()
How do I get the label of the cell when it is selected and then also pass that to another ViewController?
I have managed to get:
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!;
println(currentCell.textLabel.text)
}
I just cant figure out how to pass that as a variable to the next UIViewController.
Thanks
Passing data between two view controllers depends on how view controllers are linked to each other. If they are linked with segue you will need to use performSegueWithIdentifier method and override prepareForSegue method
var valueToPass:String!
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!;
valueToPass = currentCell.textLabel.text
performSegueWithIdentifier("yourSegueIdentifer", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "yourSegueIdentifer") {
// initialize new view controller and cast it as your view controller
var viewController = segue.destinationViewController as AnotherViewController
// your new view controller should have property that will store passed value
viewController.passedValue = valueToPass
}
}
If your view controller are not linked with segue then you can pass values directly from your tableView function
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!;
let storyboard = UIStoryboard(name: "YourStoryBoardFileName", bundle: nil)
var viewController = storyboard.instantiateViewControllerWithIdentifier("viewControllerIdentifer") as AnotherViewController
viewController.passedValue = currentCell.textLabel.text
self.presentViewController(viewContoller, animated: true , completion: nil)
}
You asked:
How do I get the label of the cell when it is selected and then also pass that to another ViewController?
I might suggest rephrasing the question as follows: "How do I retrieve the data associated with the selected cell and pass it along to another view controller?"
That might sound like the same thing, but there's an important conceptual distinction here. You really don't want to retrieve the value from the cell label. Our apps employ a MVC paradigm, so when you want to pass data information from one scene to another, you want to go back to the model (the items array), not the view (the text property of the UILabel).
This is a trivial example, so this distinction is a bit academic, but as apps get more complicated, this pattern of going back to the model becomes increasingly important. The string representation from the cell is generally is a poor substitute for the actual model objects. And, as you'll see below, it's just as easy (if not easier) to retrieve the data from the model, so you should just do that.
As an aside, you don't really need a didSelectRowAtIndexPath method at all in this case. All you need is a segue from the table view cell to the destination scene, give that segue a unique identifier (Details in my example), and then implement prepare(for:sender:):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DetailsViewController {
let selectedRow = tableView.indexPathForSelectedRow!.row
destination.selectedValue = items[selectedRow]
}
}
Alternatively, if your segue is between the cell and destination scene, you can also use the sender of the prepare(for:sender:):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DetailsViewController {
let cell = sender as! UITableViewCell
let selectedRow = tableView.indexPath(for: cell)!.row
destination.selectedValue = items[selectedRow]
}
}
But the idea is the same. Identify what row was selected, and retrieve the information from the model, the items array.
The above is Swift 3. For Swift 2.3, please see the previous version of this answer.
Okay..Its been 2 days I was searching for the answer that how could I be able to save the selected UITableViewCell label text data and display that data to an another label on an another View Controller which will come out after tapping on a cell. At last I have completed with the task and its successful. Here is the complete code with steps using Swift.I am using Xcode 6.4.
Step 1.
I have Two class assigned to the storyboard view controllers named "iOSTableViewControllerClass.swift" which is a Table View Controller and "iOSTutorialsViewControllerClass.swift" which is a normal View Controller.
Step 2.
Now make segue from iOSTableViewControllerClass to iOSTutorialsViewControllerClass by Control-dragging on the storyboard area and choose "show" from drop down menu. Click on this highlighted button according to the below image and perform the segue.
Step 3.
Now select the segue by clicking on the storyboard and give it an identifier on the Attributes Inspector. In this case I named it as "iOSTutorials"
Step 4.
Now on this step put a label on your cell as well as on the other view controller and make outlets of them on their corresponding classes.
In my case those are "#IBOutlet weak var iOSCellLbl: UILabel!" and " #IBOutlet weak var iOSTutsClassLbl: UILabel!".
Step 5.
Make a string type variable on the first Table View Controller Class. I did this as "var sendSelectedData = NSString()" also Make a string type variable on the second class. I did this as "var SecondArray:String!".
Step 6.
Now we are ready to go.
Here is the complete Code for first Class --
// iOSTableViewControllerClass.swift
import UIKit
class iOSTableViewControllerClass: UITableViewController, UITableViewDataSource,UITableViewDelegate {
// Creating A variable to save the text from the selected label and send it to the next view controller
var sendSelectedData = NSString()
//This is the outlet of the label but in my case I am using a fully customized cell so it is actually declared on a different class
#IBOutlet weak var iOSCellLbl: UILabel!
//Array for data to display on the Table View
var iOSTableData = ["Label", "Button", "Text Field", "Slider", "Switch"];
override func viewDidLoad() {
super.viewDidLoad()
//Setting the delegate and datasource of the table view
tableView.delegate = self
tableView.dataSource = self
//Registering the class here
tableView.registerClass(CustomTableViewCellClassiOS.self, forCellReuseIdentifier: "CellIDiOS")
//If your using a custom designed Cell then use this commented line to register the nib.
//tableView.registerNib(UINib(nibName: "CellForiOS", bundle: nil), forCellReuseIdentifier: "CellIDiOS")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return iOSTableData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let CellIDentifier = "CellIDiOS"
//In this case I have custom designed cells so here "CustomTableViewCellClassiOS" is the class name of the cell
var cell:CustomTableViewCellClassiOS! = tableView.dequeueReusableCellWithIdentifier(CellIDentifier, forIndexPath: indexPath) as? CustomTableViewCellClassiOS
if cell == nil{
tableView.registerNib(UINib(nibName: "CellForiOS", bundle: nil), forCellReuseIdentifier: CellIDentifier)
cell = tableView.dequeueReusableCellWithIdentifier(CellIDentifier) as? CustomTableViewCellClassiOS
}
//Here we are displaying the data to the cell label
cell.iOSCellLbl?.text = iOSTableData[indexPath.row]
return cell
}
override 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! CustomTableViewCellClassiOS!;
println("\(currentCell)")
println("\(currentCell.iOSCellLbl?.text!)")
//Storing the data to a string from the selected cell
sendSelectedData = currentCell.iOSCellLbl.text!
println(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("iOSTutorials", 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 == "iOSTutorials"{
//Creating an object of the second View controller
let controller = segue.destinationViewController as! iOSTutorialsViewControllerClass
//Sending the data here
controller.SecondArray = sendSelectedData as! String
}
Here is the complete code for the second Class..--
// iOSTutorialsViewControllerClass.swift
import UIKit
class iOSTutorialsViewControllerClass: UIViewController {
//Creating the Outlet for the Second Label on the Second View Controller Class
#IBOutlet weak var iOSTutsClassLbl: UILabel!
//Creating an array which will get the value from the first Table View Controller Class
var SecondArray:String!
override func viewDidLoad() {
super.viewDidLoad()
//Simply giving the value of the array to the newly created label's text on the second view controller
iOSTutsClassLbl.text = SecondArray
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I do it like this.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedName = nameArray[indexPath.row]
let newView: nextViewName = self.storyboard?.instantiateViewController(withIdentifier: "nextViewName") as! nextViewName
newView.label.text = selectedValue
self.present(newView, animated: true, completion: nil)
}

Resources