Swift - segue from custom cell and cell data passing to another controller - swift

I'm stuck now for hours with a problem when trying to pass data from a tableview custom cell to another viewcontroller.
To be more precise:
TableViewController1 has CustomCell1 as a Prototype Cell class
CustomCell1 has Button1, Button2, Label1 and Label2
ViewController2 has Label3
The TableViewController1 is populated fine and has 10-20 rows of data and everything is displayed fine on screen.
When the user taps on Button1 or Button2 (from what I've seen this triggers the IBAction of the button and not selecting the row) I trigger a segue programmatically from the IBAction of the button I've added to TableViewController1.
What I can't figure out is how to pass the Label1 text when user taps Button1 and Label2 text when user taps Button2 to ViewController2 and display the appropriat text in Label3.
As there is no row selected in the tableview how can this be done if possible?
Thank you!
Kostas

Make sure you have prepared your segue properly. That was my hangup when I first tried.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "showTea"){
let selectedIndexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
let genView:genViewController = segue.destinationViewController as! genViewController
genView.row = selectedIndexPath.row
}
else if (segue.identifier == "addTea"){
}
}
Then in my genViewController, I added the var row to hold the value for the row so when I pulled the data in genViewController it would pull the correct data.
var row: Int = 0
See my question on this subject and hope this helps.
core data swift sugue not pushing data to second view controller

Related

Swift save text to an instance/global variable when UIButton is pressed

So I have a UItextfield and a UIButton I was wondering if there is a way to save the text after the button is pressed in an instance variable so that I could use it in my other class.
The thing I am trying to do is to have a user input some text in the textfield on screen 1 and then when the user taps the button I want to take him to screen 2 however in the class of that screen 2 I want to know what text user entered in order to display data accordingly.
Right now I just have an action function for the button and I access text inside it and save it to an instance variable but when I call it in my other class it is empty because I initialized it as empty. So can somebody please help me and tell me how to go about this.
Thanks!
Here is the code for first screen
var searchRecipe = ""
#IBAction func SearchButton(sender: UIButton) {
if let recipe = RecipeSearchBar.text {
searchRecipe = recipe
}
}
Here is the code for second screen. I have connected the button in first screen this screen so when user taps the button he gets here.
var recipeName:[String] = []
var imageURL:[String] = []
var timeInSeconds:[Float] = []
func apiCall()
{
//search recipe API call
var searchRecipe = ""
searchRecipe = RecipesViewController().searchRecipe
print (searchRecipe) //prints nothing
endpoint = "http://api.yummly.com/v1/api/recipes?_app_id=apiId&_app_key=apiKey&q=\(searchRecipe)" //this is where I want to use the searchRecipe text from class 1
}
Well personally I would do what follows (Based on my interpretation of your issue):
Please note that I take for granted you are implementing a view-controller-based navigation and you know what IBOutlets, IBActions & Segues are
In the first view controller create an IBOutlet property of
UITextField named RecipeSearchBar and connect it to the relative text
field.
In the second view controller create a variable value of type
string;
Change the storyboard segue identifier to "toSecondViewController"
Then in the first view controller create an IBAction to be called
when the UIButton is pressed.
In your case:
#IBAction func SearchButton(sender: UIButton) {
if let recipe = RecipeSearchBar.text {
searchRecipe = recipe
}
//If you are navigating into a new view view controller
//here you need to call self.presentViewController(...)
}
Inside this action, you are going to call self.presentViewController
to display your second view controller, but you have to do one last
very important step: pass the value of the UITextField to the instance
that will hold the second view controller
To achieve this, override prepareForSegue in your first view controller
and share the UITextField value. This method is triggered once you called self.presentViewController for further implementation.
//Did not tested the code but should just be ok
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "toSecondViewController")
{
//Create the instance
let secondViewController = segue.destinationViewController
//Set the value
secondViewController.value = searchRecipe;
}
}
You are now good to go.
Hope this helped, if so mark the question for others.
Bye

NSUserDefaults changing every segue

Sorry for the newbie question but i am really stuck.
I have a UIViewController and 4 tableviews in an app. When i click on a button on the UIViewcontroller it segues to a UITableviewController called "Beach". When the user clicks on a cell of the table, it segues back to the UIViewController and displays the selected cells title as the buttons title. The problem that i am having is when i click on a nother button to a tableview and then clicks on the cell, the previous buttons title sets back to the previous title.
i have a prepare for segue function in the tables view controllers and this returns the selected table title (named : Titleoftable) to the main VC which, the strings.
the way i am currently doing it is to make a NSUserDefault below but the problem still remains the same - The value changes top "" every time i click on another table V---
let path = tableView.indexPathForSelectedRow
let cell = tableView.cellForRowAtIndexPath(path!)
let persistenceStoreKey = "MyStringKey"
let stringToStore = "\((cell?.textLabel?.text!)!)"
// Store data
NSUserDefaults.standardUserDefaults().setObject(stringToStore, forKey: persistenceStoreKey)
NSUserDefaults.standardUserDefaults().synchronize()
// Get data
let myStringt = NSUserDefaults.standardUserDefaults().stringForKey(persistenceStoreKey)
destination.textOfBeach = (myStringt)!
destination.isBeachSelected = true
}
I have been stuck on this problem for ages now! PLEASE HELP!!
PS- I am using swift-2 and Xcode7
Make sure that you are not pushing a new ViewController after you click on the tableview's cell. It gives me the impression that it might be the case since you are seeing only the title of the last cell you pressed.. Make sure you actually pop the tableview's controller instead of pushing a new one.
If you want to keep using NSUserDefaults, you could just call
navigationController?.popViewController(animated: true)
in your cellSelection function, and read the defaults value in the viewWillAppear of the main ViewController.
override func viewWillAppear(_ animated: Bool) {
let userDefault = NSUserDefaults.standard()
if let beachSelection = userDefault.string(forKey: "BeachControllerSelection") {
textOfBeach = beachSelection
isBeachSelected = true
}
//same for the rest of the other table view's selections
}

Swift - Button action not triggered in table view cell

I have a ViewController who contains a TableView. I want in each cell, a red button who did something (let's say 'hello' for test), or when I touch the cell anywhere but not on the button I perform a segue.
But even when I touch the button, it's the segue who perform. I tried some search on SF but none of the questions help me...
I don't know if that's usual but when I touch the cell, all the row white background become gray, even the background of the red button.
In storyboard I have this cell hierarchy :
The user interaction is enabled on both cell and button.
In the questions I found they said, on the cell set 'accessory' on 'disclosure indicator', I did it, but if it's possible I would like to keep it at 'None'.
Also I set a custom class for the cell, here is the code :
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var rentButton: UIButton? // I use this class for 2 tableview almost similar, but in the other I don't have the redButton, that's why I put an '?'
}
I also set the delegate and datasource of the tableView to my ViewController, here is the code of my view controller :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MyTableViewCell
cell.rentButton!.tag = indexPath.row
cell.rentButton!.addTarget(self, action: #selector(MyViewController.rent(_:)), forControlEvents: .TouchUpInside)
return cell
}
// Rent() is never called:
func rent(sender: UIButton) {
print("here \(sender.tag)")
}
EDIT : The solution was to put out the button from the conainer view !
You can stop the segue from actioning when the button is pressed by performing it programatically. You can do the following:
Remove your segue that goes from the cell to another view controller and change it go from the TableViewController to the other view controller
Create a variable in your TableViewController class such as: var buttonPressed = false
In your button action set buttonPressed to true
In didSelectRow, check that buttonPressed is not true then performSegue and change buttonPressed to false, else do nothing
As discussed, move the button from the container to the content view

How to add to an array when button is pressed?

I've got custom buttons on a custom tableview cell, when button is pressed the image changes to checked/unchecked (see code below).
Issues is: How do I add the cell row data thats checked to an array that will be its own table (eg. a table with only checked data).
#IBAction func tickAction(sender: UIButton) {
println("SSSS")
if (sender.selected) {
sender.setImage(UIImage(named:"Unchecked.png"), forState: .Normal)
sender.selected = false
}
else {
sender.setImage(UIImage(named:"Checked.png"), forState: .Normal)
sender.selected = true
}
}
A solution would be to extend UITableViewCell into your own class that holds the other data or holds a reference to a model that holds the data.
Ideally, the view controller should hold the models and should get notified by a view that the action took place to act accordingly. The view controller should then add the data to the other array.

Swift - Reload view with new data programmatically

I have a MainView with some buttons. If a user for example presses button 1, I do navigate to a DetailView through a segue and where I programmatically add items to the view. The user can then press next, what I would like to do when this happens is to basically clear the DetailView and programmatically add new items that are customized to button 2 in the DetailView and when the user presses next clear DetailView again and programmatically add new items that are customized to button 3 etc...
From the MainView with the buttons I use this segue to navigate to the DetailView
func btnNext_Clicked(sender:UIButton){
self.performSegueWithIdentifier("showDetailView", sender: buttonId)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetailView" {
let detailViewController = segue.destinationViewController as! DetailViewController
detailViewController.buttonId = buttonId!
}
}
But now I´m not sure how to clear the detailView and add new items when the user presses "Next". Anyone have any idea how to do this?
If you want just to remove old buttons, and create new programmatically, feel free to use something like
view.subviews.map({ $0.removeFromSuperview() })
This will remove all subviews and you will be able to create new.