How to pass cell label's value from tableView to other View? - ios

I am a beginner in IOS programming, and in a whole programming.
(I have XCODE 6.4)
I have read so many tutorials, but i haven't found the information I need.
I have a code which assign a value to a label :
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = "formuleTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! formule
let formuleCommand = formulesList[indexPath.row]
// Configure the cell...
var shortCut = formuleCommand.formuleText
cell.formuleLabel.text = shortCut
return cell
}
And then, I have a code, which have to get the label's name (I think so)
var valueToPass:String!
func tablView(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 identifier = "formuleTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath!) as! formule
valueToPass = cell.formuleLabel.text
performSegueWithIdentifier("detail", sender: self)
}
And finally, code, which passes the data from label to another ViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "detail") {
// initialize new view controller and cast it as your view controller
var viewController = segue.destinationViewController as! specialitiesViewController
// your new view controller should have property that will store passed value
viewController.passedValue = valueToPass
}
}
It have to work so:
Table view gets the data for cells (here is no code for this)
Then, method called TablView have to get cell's label.
And finally, i click on the cell and I move to another ViewController, where my Cell,s Label data prints in another Label.
But it don't work so, when I click on cell, I move to ViewController and the text in Label equals nil (i see no text). Why does it work so? Help me to fix this issue!
Thank you, for all your suggestions!

Your problem is that you're using the functiondequeueReusableCellWithIdentifier for get the cell and and this method only returns a cell if it has been marked as ready for reuse.
You need to use cellForRowAtIndexPath that is different from the delegate method, be carefull to get the cell, change your didSelectRowAtIndexPath like the following:
func tablView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
// get cell label
let cell = tableView.cellForRowAtIndexPath(indexPath) as! formule
self.valueToPass = cell.formuleLabel.text
self.performSegueWithIdentifier("detail", sender: self)
}
I hope this help you.

Related

How to access textview value which is inside tableview cell in swift 5?

I have one viewcontroller, inside that I have one table view and 2 buttons save and cancel.
In tableview cell i have one textview. after adding some text in textview i want to show that text. I am not sure how to get that tableview text on save button click. (number of rows may be dynamic).
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableview.dequeueReusableCell(withIdentifier: "SummaryManualEditContentCell", for: indexPath) as? SummaryManualEditTableCell {
cell.txtAnswers.text = "enter text here"
return cell
}
return UITableViewCell()
}
#IBAction func btnSave(_ sender: Any) {
print("textviewText1 + textviewText2 + and so on ")
}
In Addition to this on button click i want to add all that text multiple textviews into one string.
is there any clean and best way to achieve this?
Thank you for helping!
You need to get the indexPath of the cell whose text you want to get
get the cell for that indexpath like
#IBAction func btnSave(_ sender: Any) {
let indexPath = IndexPath(row: 0, section: 0)
if let cell = tableView.cellForRow(at: indexPath) as? SummaryManualEditTableCell {
let text = cell.txtAnswers.text
}
}
And if you have multiple cells with textFields you can loop around to get all fields
#IBAction func btnSave(_ sender: Any) {
var allTextViewsText = ""
for i in 0...5{
let indexPath = IndexPath(row: i, section: 0)
if let cell = tableView.cellForRow(at: indexPath) as? SummaryManualEditTableCell {
allTextViewsText += cell.txtAnswers.text
}
}
print(allTextViewsText)
}
But keep it in mind that this approach only works in the case of visible cells otherwise for non visible cells you will get nil
I will suggest you to implement textView:shouldChange in each cell who has textView with a delegate to the tableView's viewController. When text is changed in the cell, delegate should propagate the change to the viewController which will save the value in a variable.
Then, when you press on the save button, you would simply take values from variables.

ios Swift: Passing data from tableView to view controller

enter image description herewell this is my first time posting a question so not to sure how it works. I am doing an assignment on swift. I am stuck at a point where I need to pass the data from tableview to viewcontroller. On my first ViewController, I have a list of data (Categories) coming from the database table and when the user clicks on any of the cell, it should go to the next viewcontroller the label becomes the heading. Please find my screen shot attached.
Thanks
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return values.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CategoryList_TableViewCell
let maindata = values[indexPath.row]
cell.categoryLabel.text = maindata["NAME"] as? String
return cell;
}
I tried using didSelectRowAtIndexpath and perparesegue functions but not getting my head around.
can anyone can guide me.
Thanks a million in advance :)
You don't need to implement didSelectRow just to pass data through a segue. Assuming you're using Storyboards.
CTRL drag from the prototype TableViewCell in your storyboard to the ViewController you want to pass data to.
Choose Show for the segue type and give it an identifier
Do this in prepareForSegue:
if segue.identifier == "catView" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let controller = segue.destinationViewController as! YourViewController
let value = values[indexPath.row]
controller.catTitleRec = value["NAME"] as! String
}
Do this in your didSelectRowAtIndexPath:
let maindata = values[indexPath.row]
self.performSegueWithIdentifier("yourIdentifier", sender: mainData)
Then, in your prepareForSegue function do this:
let destinationVC = segue.destinationViewcontroller as! YourCustomViewController
destinationVC.yourObject = sender as! YourObject

Tap button in tableview - wrong cell

Hi I am trying to pass a variable in the cell which is the label when i click on a button in the cell. but the problem is every when I put the code in cellForRowAtIndexPath, it gets the label from the wrong cell every time. why and how to fix this?
var variableToPass: String!
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : MainCell! = tableView.dequeueReusableCellWithIdentifier("MainCell") as! MainCell
variableToPass = label1.text
cell.label1.userInteractionEnabled = true
let tapButton = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapLabel(_:)))
cell.label1.addGestureRecognizer(tapButton)
return cell as MainCell
}
func tapButton(sender:UITapGestureRecognizer) {
performSegueWithIdentifier("SegueIdentifierName", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SegueIdentifierName" {
let viewController = segue.destinationViewController as! ViewController
viewController.getVariablePassed = variableToPass
}
}
The way your code is set up, variableToPass is always the text in the last cell acquired from dequeueReusableCellWithIdentifier. Instead, set variableToPass in your tapButton method, because then you know what cell was selected and you can correctly set variableToPass:
func tapButton(sender:UITapGestureRecognizer) {
let label = sender.view as! UILabel
self.variableToPass = label.text
performSegueWithIdentifier("SegueIdentifierName", sender: self)
}
My way to do this is using a cell delegate and registering my viewController as delegate for the cell, later when the user taps on the UIButton I will call a method like
- (void)buttonWasPressedWithIndexPath:(NSIndexpath*)indexPath
and in cellForRowAtIndexPath I pass the indexPath as a cell property

How to get label on button click in tableview cell for prepareForSegue

I have a tableview. i need to get the label "usernameLabel" from that cell and assign a variable to them. I need to pass that variable to prepareForSegue. The problem is the label is the wrong label from the wrong cell.
here is what i have:
var username: String!
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : MainCell! = tableView.dequeueReusableCellWithIdentifier("MainCell") as! MainCell
username = usernameLabel.text
cell.button.userInteractionEnabled = true
let tapButton = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapLabel(_:)))
cell.button.addGestureRecognizer(tapButton)
return cell as MainCell
}
func tapButton(sender:UITapGestureRecognizer) {
performSegueWithIdentifier("ViewToView2Segue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ViewToView2Segue" {
let userProfileViewController = segue.destinationViewController as! SecondViewController
secondViewController.usernamePassed = usernamePassed
}
}
simplified question: i need to pass the label.text to another view controller via segue. but currently, it is getting the label from the wrong cell.
cellForRowAtIndexPath method will be multiple times so assigning value in that method will not work, also why are you using tapGesture on button instead of adding action to button, try to change your cellForRowAtIndex like this.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : MainCell! = tableView.dequeueReusableCellWithIdentifier("MainCell") as! MainCell
cell.button.setTitle( usernameLabel.text, forState: .Normal)
cell.button.addTarget(self, action: #selector(self.buttonAction(_:)), forControlEvents: .TouchUpInside)
return cell
}
Now add this buttonAction function inside your ViewController
func buttonAction(sender: UIButton) {
let center = sender.center
let point = sender.superview!.convertPoint(center, toView:self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(point)
let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! MainCell //Add superview on the basis of your button hierarchy in the cell
username = cell.usernameLabel.text
print(username)
performSegueWithIdentifier("ViewToView2Segue", sender: self)
}
You should not save state data in cells. You should have the info that you want in your model (probably an array). When the user taps a cell you should use the indexPath of the selected cell to fetch the info from the model, not from a label on the cell.
(Look up the MVC design pattern for background. A table view cell is a view object, and should not store data. That's the model's job.)

Passing data to a custom UITableViewCell class

ViewControllerA will be pushing to ViewControllerB. ViewcontrollerB is a UITableView that has a custom UITableViewCell that is registered upon load.
Here is my custom UITableViewCell:
override func awakeFromNib() {
super.awakeFromNib()
// Here is me attempting to pass my data from my view controller
someButton.text = stringFromViewController
}
Here's my UITableView:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let customCell = CustomCell()
customCell.stringFromViewController = "Some Text"
self.performSegueWithIdentifier("ViewControllerB", sender: nil)
}
Whenever I attempt this the string comes back as empty. I'm not sure if this has to do with the fact that I am trying to pass this data to the UITableViewCell instead of the UITableView that contains the custom cell. I'd like to pass the data to my custom cell class.
You going about this the wrong way.
your tableView is reloading automatically upon loading controller B.
you should pass the data to the cell in tableView:CellForRow: method.
you can also call tableView.reloadData() once you assign the value from controller A.
here's an example:
class ControllerB {
var tableView: UITableView! //IBOutlet?
var stringFromA: String? {
didSet {
self.tableView.reloadData()
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell")
cell.stringFromA = self.stringFromA
return cell
}
Because awakeFromNib() initilizes even before you initilize the cell.
instead of assigning it in this method use this in didSelectRowAtIndexPath
let customCell = CustomCell()
customCell.someButton.setText("Some Text", forState: .Normal)
self.performSegueWithIdentifier("ViewControllerB", sender: nil)
My understanding of your question is that clicking on a row from View Controller A will push View Controller B and you want to pass some data to the custom cell in View Controller B. you have to use prepareForSegue to pass the data.
in view controller b, set a variable, and in your case, a bool.
class ViewControllerB {
var boolValue: Bool?
}
then in didSelectRowAtIndexPath in ViewControllerA you perform the segue
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("ViewControllerB", sender: nil)
}
Then you have to perform prepareForSegue according to the row being selected
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "ViewControllerB" {
//if you need to know which row is select, use indexPath.row
if let indexPath = tableView.indexPathForSelectedRow {
let controller = segue.destinationViewController as! ViewControllerB
//send the details that you want, i.e
if indexPath.row < 5 {
controller.boolValue = true
} else {
controller.boolValue = false
}
}
}
once the segue is called, you pass the data through prepareForSegue, then you can pass the information to the cell using cellForRowAtIndexPath method.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomTableViewCell
//pass the boolValue from viewcontrollerB to anotherBoolValue in custom cell
cell.anotherBoolValue = boolValue
// Configure the cell...
return cell
}
I agree with #Lirik
have a property observer on you controllerB's property and reload the table view, then in your cellForRowAtIndexPath(::)
cast the dequeued cell to your custom cell type so that you can access all the function of your cell
let cell:CustomCell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell") as! CustomCell
cell.someBotton.text = stringFromViewControllerA
I agree with #Lirik
have a property observer on you controllerB and reload the table view, then in your cellForRowAtIndexPath(::)
cast the dequeued cell to your custom cell type so that you can access all the function of your cell
let cell:CustomCell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell") as! CustomCell

Resources