Reputation: 139
I have searched the internet countless times and have not found a solution to my situation. Things that may be a solution are things I didn't understand and they were in Objective-C. So if this is a duplicate, it isn't. I have failed to get a solution from other posts.
I am making a GPA Calculator specifically for my school where we get different points depending on our subject levels too.
I made a UITableView with a custom cell that will be duplicated specific amount of times each for each subject in the grade.
What I want to know is getting the data from each of these custom cells(the score and the level)
So this is my storyboard:
and this is my app previewed in the simulator:
I'm going to get the score and the level by getting the text of the labels in each subjects and I have no idea how to get data from specific cells.
Thank you very much.
Here's the code i currently have:
//showStepperValueLabel shows the level and showSliderValueLabel shows the score in the cells.
//customCell is my custom class for my custom cell.
//i have already declared the levels and scores array above in my class
func tableView(tableView: UITableView!, didDeselectRowAtIndexPath indexPath: NSIndexPath!) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as customCell
var level: String! = cell.showStepperValueLabel.text
var score: String! = cell.showSliderValueLabel.text
levels[indexPath.row] = level
scores[indexPath.row] = score
}
//yadiyadayada
//and this is the part where the values get received(it's inside the prepareForSegue function)
var engScore: String = scores[0]
var engLevel: String = levels[0]
var mathScore: String = scores[1]
var mathLevel: String = levels[1]
var sciScore: String = scores[2]
var sciLevel: String = levels[2]
var geoScore: String = scores[3]
var geoLevel: String = levels[3]
var hisScore: String = scores[4]
var hisLevel: String = levels[4]
var chiScore: String = scores[5]
var chiLevel: String = levels[5]
//
But i'm getting an error where the arrays never received the values. can someone help?
EDIT:
i got an error again so i tried giving the strings manually to the arrays while its initialization like
var levels: [String] = ["H", "H", "H", "H", "H", "H"]
var scores: [String] = ["12", "23", "34", "45", "56", "67"]
and the program worked perfectly fine. So that concludes that the problem occurs in the part where the array receives the strings which is
func tableView(tableView: UITableView!, didDeselectRowAtIndexPath indexPath: NSIndexPath!) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as customCell
var level: String! = cell.showStepperValueLabel.text
var score: String! = cell.showSliderValueLabel.text
levels.insert(level, atIndex: indexPath.row)
scores.insert(level, atIndex: indexPath.row)
}
are you sure the disselect thing is the correct way? everyone else in the internet taught me to use tags however didn't tell me how to use it...
EDIT2:
so i tried using tags. this is what i wrote in the tableView: cellForRowAtIndexPath function
cell.showStepperValueLabel.tag = indexPath.row+10
cell.showSliderValueLabel.tag = indexPath.row
and this is what i wrote in the prepareForSegue
var engScore : UILabel! = self.view.viewWithTag(0) as? UILabel
var mathScore: UILabel! = self.view.viewWithTag(1) as? UILabel
var sciScore: UILabel! = self.view.viewWithTag(2) as? UILabel
var geoScore: UILabel! = self.view.viewWithTag(3) as? UILabel
var hisScore: UILabel! = self.view.viewWithTag(4) as? UILabel
var chiScore: UILabel! = self.view.viewWithTag(5) as? UILabel
var engLevel: UILabel! = self.view.viewWithTag(10) as? UILabel
var mathLevel: UILabel! = self.view.viewWithTag(11) as? UILabel
var sciLevel: UILabel! = self.view.viewWithTag(12) as? UILabel
var geoLevel: UILabel! = self.view.viewWithTag(13) as? UILabel
var hisLevel: UILabel! = self.view.viewWithTag(14) as? UILabel
var chiLevel: UILabel! = self.view.viewWithTag(15) as? UILabel
so in the functions of calculating GPA i put
//Get pxcs
engpxc = engCredits*co.getEnglishPoints(engLevel.text!, engScore: engScore.text!)
mathpxc = mathCredits*co.getNonLanguagePoints(mathLevel.text!, scoreRecieved: mathScore.text!)
geopxc = geoCredits*co.getNonLanguagePoints(geoLevel.text!, scoreRecieved: geoScore.text!)
hispxc = hisCredits*co.getNonLanguagePoints(hisLevel.text!, scoreRecieved: hisScore.text!)
scipxc = sciCredits*co.getNonLanguagePoints(sciLevel.text!, scoreRecieved: sciScore.text!)
chipxc = chiCredits*co.getChiPoints(chiLevel.text!, chiScore: chiScore.text!)
//
and now i'm getting an error that says
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
can someone help me with this?
EDIT3 - more info:
i added println in the tableView: cellForRowAtIndexPath function in parts where i give the tags and found out that the tags were given successfully and those labels received the tags i assigned in the program however when i checked with println in the prepareForSegue function in where the variables receive their views to see if they received the labels successfully but i got 'nil' there. What in the world is the problem?
Upvotes: 6
Views: 47008
Reputation: 324
I know this is a very old post but then to if it helps someone I'll be happy so to do this the simple way which I will prefer is made an array of the UI table view cell and called it in the UI View Controller and then this becomes very simple just called the array (Thanks to rohan)
(FOR EXAMPLE)
import UIKit
public class PlanningTableView:UITableViewCell{
@IBOutlet weak var Sccode: UITextField!
@IBOutlet weak var NoOfPatients: UITextField!
}
(AND NOW IN VIEW CONTROLLER DO THIS)
import UIKit
class PlanningReport:UIViewController,UITableViewDelegate,UITableViewDataSource{
var ScCode = [String]()
var NoOfPatient = [String]()
var CollectionOfCell = [PlanningTableView]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PlanningTableView
CollectionOfCell.append(cell)
return cell
}
//////// Then at sumbmit Button just do this /////////////////
@IBAction func Submit(_ sender: Any) {
CollectionOfCell.forEach { cell in
ScCode.append(cell.Sccode.text!)
NoOfPatient.append(cell.NoOfPatients.text!)
}
}
For more details I just created a YouTube first ever tutorial - comments good/bad appreciated
Upvotes: 4
Reputation: 7948
First retrieve your cell where you need it (for instance in didSelectRowAtIndexPath). Cast your UITableViewCell in your custom cell. And then access properties of your cell as you wish.
Since you haven't provided any code, I will provide simply examples of the code:
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as YourCell
//cell.value, cell.text, cell.randomValue or whatever you need
}
What about submit button, you want to submit the data right? And you don't have indexPath there...
Well you have several options, one is to go through each cell, check the type and get it. But seems like your each cell is different one. And seems like you have order for these cells. So you know where exactly your result will be. So, in submit you can do the following
@IBAction func submit_pressed(sender: UIButton) {
var indexs = NSIndexPath.init(index: 10)
// or which one(s) you need. you extract data from the cell similar to previous function
}
But, why do you have to get entire cell to get one value? How about you create few variables (or even better, array) and extract values there? you can link events to these controls and when they change you get these value and save them. Later on, you can use these values(or array) without accessing cells or retrieving them.
EDIT:
How about tags? I am not sure if you are adding this through code or storyboard, but I will go through both of them.
In cellForRowAtIndexPath, you can simply say cell.tag = indexPath.row
, or even better: cell.tag = question.id
( assuming that question is your custom class). That way, you can go through questions and take specific ones.
Here is working code with tags:
@IBAction func test(sender: AnyObject) {
var lbl : UILabel = self.tableView.viewWithTag(12) as UILabel!
var cell : UITableViewCell = self.view.viewWithTag(3) as UITableViewCell!
return ;
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = indexPath.row == 0 ? tableView.dequeueReusableCellWithIdentifier("firstCell", forIndexPath: indexPath) as UITableViewCell : tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
if(indexPath.row != 0){
let item = toDoList[indexPath.row-1]
cell.textLabel?.text = item.title
NSLog("%d",indexPath.row)
var integerncina = (indexPath.row + 10) as NSInteger!
cell.textLabel?.tag = integerncina
NSLog("%d", cell.textLabel!.tag)
cell.tag = indexPath.row
}
// Configure the cell...
return cell
}
Upvotes: 12
Reputation: 741
To collect data from your cells after the user has finished entering the data (score and level), you can use the UITableView
delegate method tableView:didDeselectRowAtIndexPath
[Deselect]
The code in your instance will go in UITableViewController
class and will look something like this.
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as YourCustomCellClass
var levelArray:[String] = [] //Assuming you want to collect and store your cell data in an Array. You may use a Dictionary as well, whichever is more convenient.
var scoreArray:[String] = []
// levelArray.append(cell.levelLabel.text!)
// scoreArray.append(cell.scoreLabel.text!)
levelArray.insert(cell.levelLabel.text!, atIndex: indexPath.row)
scoreArray.insert(cell.scoreLabel.text!, atIndex: indexPath.row)
}
Next, in you submit button's action(Selector) function use the 'levelArray' and 'scoreArray' to pass your collected data. Be sure to declare the array/dictionary variables(ex: levelArray) right under your UITableViewController
class declaration, like so
class GpaCalculator: UITableViewController {
var levelArray:[String] = []
var scoreArray:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
}
// ...
}
..to be able to use it in other functions like your submit button's action(Selector) function.
Upvotes: 3