How to retrieve the array from UITableViewController to ViewTable - ios

I'v tried to get array from UITableViewController to another ViewController. I have navigationController and main screen is MyTableViewController. I'm trying to pass data with Segue. Here is the part of MyTableViewController. All other code in this file are correct.
MyTableViewController
struct Faculty {
var name = String()
var descriptions = [String]()
}
let faculties = [
Faculty(name: "Faculty of Architecture", descriptions: ["Architecture and Urban Planning", "Spatial Planning"]),
Faculty(name: "Faculty of Civil Engineering", descriptions: ["Civil Engineering"]),
Faculty(name: "Faculty of Chemistry", descriptions: ["Biotechnology", "Chemistry","Chemical and Process Engineering", "Materials Science and Engineering", "Chemical Technology"]),
Faculty(name: "Faculty of Electronics", descriptions: ["Control Engineering and Robotics", "Electronics", "Telecommunications", "Teleinformatics", "Technical Computer Science"])]
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "showDetail", sender: cell)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail",
let indexPath = self.tableView.indexPathForSelectedRow {
let sendDescriptions = faculties[indexPath.row].descriptions
let destination = segue.destination as? ViewController
destination?.getDescriptions = sendDescriptions
}
}
ViewController
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
var getDescriptions = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(getDescriptions)
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return getDescriptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "detailIdentifier", for: indexPath)
let row = indexPath.row
cell.textLabel?.text = getDescriptions[row]
return cell
}

Related

Can't pass realm data from tableViewController to viewController

I'm having difficulty with passing a realm object's data from a tableViewController to a viewController. I want to choose one of the objects from the table and have that object's data be used in the following viewController. I've struggled to find resources here which deal with Realm objects instead of just passing strings and the likes. Any assistance would be great.
Here's my TableViewController with my attempt at creating a segue function to the second view :
class WorkoutController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return DBHelper.shared.getWorkout().count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
let muscle = DBHelper.shared.getWorkout()[indexPath.row]
cell.textLabel?.text = muscle
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let workoutDetailVC = segue.destination as! WorkoutDetail
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let name = DBHelper.shared.getWorkout()[indexPath.row]
workoutDetailVC.receivedName = name
}
}
}
Here's the WorkoutDetail class which is supposed to receive and show the data :
class WorkoutDetail: UIViewController {
#IBOutlet weak var muscleLabel: UILabel!
var receivedName = ""
override func viewDidLoad() {
super.viewDidLoad()
muscleLabel.text = receivedName
}
}
Here is the getWorkout() function referenced above :
func getWorkout()-> [String] {
var musclesName = [String]()
let storedExercise = realm.objects(Workout1.self)
for exercise in storedExercise {
musclesName.append(exercise.exercise)
}
return musclesName
}
I'm having real difficulty with this and would very much appreciate some assistance, thanks.
Get didSelectRowAt out of prepare then
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
let muscle = DBHelper.shared.getWorkout()[indexPath.row]
cell.textLabel?.text = muscle
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let name = DBHelper.shared.getWorkout()[indexPath.row]
self.performSegue(withIdentifier:"SegueName",sender:name)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let workoutDetailVC = segue.destination as! WorkoutDetail
workoutDetailVC.receivedName = sender as! String
}

pass data from tableview to another tableview

I am a beginner in swift and I really want to fix this problem. What I am trying is to pass data from tableview to another but when I run the code, it only show me a blank tableview. Here is my code in source tableviewcontroller:
import UIKit
class C1TableViewController: UITableViewController {
var categorisePagePOneName = ["CLOTHING", "SHOES", "ACCESSORIES", "THEME"]
var selectedIndex = Int()
override func viewDidLoad() {
super.viewDidLoad()
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categorisePagePOneName.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdt = "Conecell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdt, for: indexPath) as! C1TableViewCell
cell.textLabel?.text = categorisePagePOneName[indexPath.row]
// Configure the cell...
return cell
}
func laodForNextPage(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath, segue: UIStoryboardSegue, sender: AnyObject?) {
performSegue(withIdentifier: "connect2", sender: self)
self.selectedIndex = indexPath.row
if segue.identifier == "connect2" {
let vc = segue.destination as! C2TableViewController
vc.firstRow = categorisePagePOneName[self.selectedIndex]
}
}
}
Then here is my code in another tableViewController:
import UIKit
class C2TableViewController: UITableViewController {
var firstRow: String!
var secondArray: [String] = []
var clothingCat = ["ALL CLOTHING", "THEME", "JACKET", "T-SHIRT", "SHIRT", "SWEATSHIRT", "HOODIES", "PANTS", "JEANS", "SHORTS", "KNITWEAR", "VESTS"]
var shoesCat = ["ALL SHOES", "THEME", "BOOTS", "SANDALS", "SNEAKERS"]
var asscessoriesCat = ["ALL ASSCESSORIES", "THEME", "HAT","BAGS", "JEWELLERY", "EYEWEAR", "WATCHES", "WALLETS", "SOCKS", "UNDERWEAR"]
var themeCat = ["VINTAGE", "KOREA","JAPAN", "SPORTY"]
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return secondArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "C2", for: indexPath) as! C2TableViewCell
// Configure the cell...
switch firstRow {
case "CLOTHING":
secondArray = clothingCat
case "SHOES":
secondArray = shoesCat
case "ASSCESSORIES":
secondArray = asscessoriesCat
case "THEME":
secondArray = themeCat
default:
break
}
cell.textLabel?.text = secondArray[indexPath.row]
return cell
}
}
I am not sure if I am using switch in this case correctly
Replace (the custom method laodForNextPage is useless anyway)
func laodForNextPage(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath, segue: UIStoryboardSegue, sender: AnyObject?) {
performSegue(withIdentifier: "connect2", sender: self)
self.selectedIndex = indexPath.row
if segue.identifier == "connect2" {
let vc = segue.destination as! C2TableViewController
vc.firstRow = categorisePagePOneName[self.selectedIndex]
}
}
with
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
performSegue(withIdentifier: "connect2", sender: indexPath)
}
and implement
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "connect2" {
let indexPath = sender as! IndexPath
let vc = segue.destination as! C2TableViewController
vc.firstRow = categorisePagePOneName[indexPath.row]
}
}
And you can delete selectedIndex
You need to add this function while the sender is the indexPath
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}

Issues displaying a table view cell from one view controller to another

Right now I am trying to move information from my goal cell into a new table view cell, and am having difficulty getting the cell to display.
Here is the code for my goal cell.
import UIKit
class GoalsViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var Goals: [String] = ["goal 1", "goal 2", "goal 3"]
let theEmptyModel: [String] = ["No data in this section."]
var valueToPass = ""
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func showGoalSelected() {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
let popUp = GoalSelectedPopUp()
self.view.addSubview(popUp)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "GoalConversationsCell_1") {
let viewController = segue.destination as! ActiveGoalsViewController
viewController.Goals.append([valueToPass])
}
}
}
extension GoalsViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Goals.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "GoalCell_1", for: indexPath)
cell.textLabel?.text = Goals[indexPath.row]
cell.textLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
cell.textLabel?.numberOfLines = 3
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
valueToPass = Goals[indexPath.row]
performSegue(withIdentifier: "activeGoalsSegue", sender: self)
Goals.remove(at: indexPath.row)
if Goals.count != 0 {
showGoalSelected()
} else {
Goals.append(contentsOf: theEmptyModel)
}
tableView.reloadData()
}
}
Here is the goal cells storyboard with the push segue connecting it to the other table view.
That other table view is shown below.
Here is the code for this new tableview.
import UIKit
class ActiveGoalsViewController: UIViewController {
#IBOutlet weak var goalTableView: UITableView!
let sections: [String] = ["Mark as Complete:", "History:"]
var goals: [[String]] = [[], []]
let theEmptyModel: [String] = ["No data in this section."]
extension ActiveGoalsViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Goals[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TodayGoalViewCell_1", for: indexPath) as? GoalTableViewCell
cell?.goalLabel.text = Goals[indexPath.section][indexPath.row]
cell?.cellDelegate = self
cell?.index = indexPath
return cell!
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return Goals.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
if Goals[0] != theEmptyModel {
Goals[1].append(Goals[0][indexPath.row])
if Goals[1].first!.contains("No data in this section.") {
Goals[1].removeFirst()
}
Goals[0].remove(at: indexPath.row)
if Goals[0].count == 0 {
Goals[0].append(contentsOf: theEmptyModel)
}
tableView.reloadData()
}
}
}
Once the goal is selected, it sends me to the new storyboard, but this new view does not display the goal that was just added. Can someone help me figure out why this isn't working? Thanks.
I think in the second view controller you need to access the "goals" variable with a lower case g rather then the "Goals" variable with an upper case G.

pass data from one tableview to another using segue and didSelectRowAt

I have already shown a list of metro station on the screen, what I want to do is when clicking different stations, they can pass their information to the second tableview and display, how to do that by using segue and didselectRowAt?
tablecell class
class LandmarksTableViewCell: UITableViewCell {
#IBOutlet weak var LandmardsImage: UIImageView!
#IBOutlet weak var LandmarksLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
metrostationViewController
class MetroStationsViewController: UITableViewController{
let wmataapimanager = WmataAPIManager()
let locationDetector = LocationDetector()
var stations = [Station](){
didSet{
tableView.reloadData()
}
}
var landmarks = [Landmark]()
override func viewDidLoad(){
super.viewDidLoad()
wmataapimanager.delegate = self as FetchStationsDelegate
locationDetector.delegate = self as LocationDetectorDelegate
fetchStation()
}
private func fetchStation(){
locationDetector.findLocation()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return stations.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "StationCell", for: indexPath) as! StationsTableViewCell
let station = stations[indexPath.row]
cell.StationLabel.text = station.name
//cell.LaiLabel.text = String(station.Lat)
//cell.LonLabel.text = String(station.Lon)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("you select: \(indexPath.row)")
let selectStation = stations[indexPath.row]
let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
}
}
In didSelectRowAt delegate method perform segue and as sender pass selected station
performSegue(withIdentifier: "identifier", sender: stations[indexPath.row])
then you should have variable in destination ViewController and you can assign this variable in prepare for segue method as downcasted sender
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "identifier" {
let destinationVC = segue.destination as! DestinationViewController
destinationVC.station = sender as! Station
}
}

Can't pass through data to second controller with segue

I can't get a simple segue to work when a cell in a tableview gets pressed. It does go to the next view after I tapped two different items. But I can't pass any values from the first controller to the second. If I set a value to the label in the second controller and load it in the viewDidLoad method it shows up.
I'm going crazy as I've been trying to get this work for ages....
My storyboard: https://snag.gy/DCw9MU.jpg
CategoryListViewController(1st controller):
import Foundation
import UIKit
class CategoryListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var categoryList = TestData.sharedInstance.categoryList
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "iEngineer"
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tableView .reloadData()
tableView.dataSource = self
for category in categoryList{
print(category)
}
}
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showFormulaList" {
if let indexPath = tableView.indexPathForSelectedRow {
let category = self.categoryList[indexPath.row]
let formulaListViewController = (segue.destination as! UINavigationController).topViewController as! FormulaListViewController
formulaListViewController.text = category
formulaListViewController.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
formulaListViewController.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// MARK: - Table View
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(categoryList.count)
return categoryList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "categoryCell", for: indexPath)
let object = categoryList[indexPath.row]
cell.textLabel!.text = object
return cell
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showFormulaList", sender: self)
}
}
FormulaListViewController(2nd controller):
import Foundation
import UIKit
class FormulaListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var titleLabel: UILabel!
var formulaList = TestData.sharedInstance.formulaList
var fSwift: String!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "iEngineer"
print(fSwift)
titleLabel.text = fSwift
}
// MARK: - Table View
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(formulaList.count)
return formulaList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "formulaCell", for: indexPath)
let object = formulaList[indexPath.row]
print(object)
cell.textLabel!.text = object
return cell
}
}
Where is my mistake or what am I doing wrong?
I greatly appreciate any help
You need didSelectRowAt instead of didDeselectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showFormulaList", sender: self)
}
Also make sure segue source is the vc not the cell , and since you fire the segue in didDeselectRowAt this
if let indexPath = tableView.indexPathForSelectedRow
will be nil
You have used didDeselectRowAt:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showFormulaList", sender: self)
}
You need to use didSelectRowAt:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showFormulaList", sender: self)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showFormulaList", sender: self)
}
You should use didSelect instead of didDeselectRowAt, also you should pass something better than self, because with self you are passing the entire CategoryListViewController
Try to pass the indexPath like this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showFormulaList", sender: indexPath)
}
and change the function prepare in this
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showFormulaList" {
if let indexPath = sender as? IndexPath {
let category = self.categoryList[indexPath.row]
let formulaListViewController = (segue.destination as! UINavigationController).topViewController as! FormulaListViewController
formulaListViewController.fuckSwift = category
formulaListViewController.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
formulaListViewController.navigationItem.leftItemsSupplementBackButton = true
}
}
}
If this doesn't help you try to debug your code and find where you lost your variable :)

Resources