I am still trying to make sense of this idea myself so if I am unclear I apologize. If there are more questions please ask instead of down voting.
Im my app I have a tableview populated with restaurant names that I am querying from parse. What I want to do is: when the user clicks on a cell I want to have have the cell segue to a tableView populated with that restaurants menu.
Now, my question is:
1. How can I have the segue identify the parse ID of the restaurant selected at the indexPath and have this ID input into the query for the appropriate menu in the parse database.
You can use prepareForSegue to get a reference to the view controller you're passing the information to, and set that info before you segue to it, so that your new view controller has the appropriate Parse object. As well as a reference to the new view controller, you can also get a reference to the index path that was selected, and use your data source to pass the information along.
When user clicks on a particular row of tableView, didSelectRowAtIndexPath will be triggered. So, you can get the name of the restaurant user clicked by getting the element at index path. See ex below.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let index = self.tableView.indexPathForSelectedRow?.row
//assuming listOfRestaurants is your list of restaurants
let restaurantName = listOfRestaurants[index!] as String
//now you can query the database with the restaurantName to get details
//once you get the details Object
performSegueWithIdentifier(segueId!, sender: self)
//here segueId is the name of your segue identifier
}
//later in your prepareForSegue method pass the data you retrieved from database to the new View controller. Ex follows.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//considering restaurantDetailsSegue as your segue id
if (segue.identifier == "restaurantDetailsSegue") {
let NVC: newViewController = segue.destinationViewController as! newViewController
NVC.details = details
}
}
Hope it helps.
Related
I want to pass a different url to the next VC compared to which cell the user selected via my prepare segue but how can I do that ? Thanks !
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let idGenderMovie = gendersDataModel[indexPath.row].id
let urlString = "https://api.themoviedb.org/3/discover/movie?api_key=&with_genres=\(idGenderMovie)"
performSegue(withIdentifier: "showMovies", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let showMovieFilteredVC = segue.destination as? ShowFilteredMovie else {return}
showMovieFilteredVC.urlGender = //???
}
As Matt says in his comment, you know which cell was selected in your didSelectRowAt() method. You extract a URL from your data model using the user's selected row, fetch some data from that URL, and then drop that information on the floor.
Instead, create an instance variable in your view controller, userSelectedRow, and set it in your didSelectRowAt() method. Then, in your prepareForSegue, use the selected row to fetch the info you need and pass it to your destination view controller.
EDIT:
Or, as Matt suggests, don't save anything. Leave the row selected, and in prepare(for:), interrogate your table view for its selected row, and use that to fetch your data.
By the way, if the URL is to a remote server, you should not read it using Data(contentsOf:). That is a synchronous call that will block your user interface until it completes. You could cause your UI to freeze for up to 2 minutes trying to read data from a remote server with that call. (And that would cause your app to be killed as unresponsive.)
so I have a UIScrollView with all of these buttons overlayed with images:
http://i.imgur.com/W6hagsa.png
and I need it so that if you click on a teacher, like Mr Edmondson for maths, In another UIViewController, an email screen pops up and it needs to set the email recipient to edmondson#gmail.com.
Basically you click on whatever teacher, and it sets the email recipient to that teacher. My current code in the recipients & message body is:
let toRecipients = ["placeholder#gmail.com"]
mc.setMessageBody("blah blah blah blah")
How would I do this ?
You may use segue in your storyboard. Then use the prepareSegue
Something like this in your TableViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailSegue" {
let vc = segue.destination as! ViewController
vc.teacher = teachers[selectedItem]
}
}
You must manage the selected teacher with a var selectedItem: Int in
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedItem = indexPath
print (selectedItem.row)
}
If it's not clear, feel free to give me more details about your code if you need more explanations.
Regards
Seb
Create a property in viewcontoller and set it in prepareForSegue method.
Have a look at the following instance method:
prepareForSegue:sender:
Use this method to let your end view controller know which teacher that you have selected and in the next view controller where you need to automatically load the teacher's email address you can do the following:
Save all your teachers data (including the names, email address etc.) into a CoreData model then load the selected teachers email address when required.
It's kind of hard to explain in detail as I have no idea how your code is structured and whatnot.
I am trying to pass value I get from Firebase to another tableView. I get 2 values from Firebase - "Brands" and "Products". I am trying to make like car app. If you click on Ford then new tableView will appear and shows all the Ford models. This is what I've done so far.
like this I get Brands from Firebase:
func parseSnusBrands(){
let ref = FIRDatabase.database().reference().child("Snuses").child("Brands")
ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if snapshot.exists() {
if let all = (snapshot.value?.allKeys)! as? [String]{
for a in all{
if let products = snapshot.value![a] as? [[String:String]]{
self.snusBrandsArray.append(["key":a,"value":products])
}
}
self.snusBrandsTableView.reloadData()
}
}
})
}
And like this I detect which cell is clicked and print the product that belongs to the clicked Brand:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
print("products at \(indexPath.row) --> \(snusBrandsArray[indexPath.row]["value"])")
}
How to pass the (snusBrandsArray[indexPath.row]["value"]) to new tableView? I tried using segues and looking for tutorials like "How to pas value between viewControllers" but I am out of luck. Right now I have 2 tableViewController.swift files and one tableViewCustomCell.swift file. Do I need some more files?
For send data, first of all declare your variable in 2nd view controller..
var productsValue = [[String:String]]()
and in 1st viewcontroller
var valueTopass = [[String:String]]()
Than in didSelectRowAtIndexPath, take a value in one valueTopass
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("products at \(indexPath.row) --> \(snusBrandsArray[indexPath.row]["value"])")
if let products = snusBrandsArray[indexPath.row]["value"] as? [[String:String]]{
valueTopass = products
performSegueWithIdentifier("toProducts", sender: self)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "toProducts") {
var viewController = segue.destinationViewController as! SnusProductsTableViewController
viewController.productsValue = valueTopass
print(productValues)
}
}
You need to use Segues to pass the data forward.
To pass data from the current view controller to the next new view controller using segues, first create a segue with an identifier in the relevant storyboard. Override your current view controller's prepareForSegue method. Inside the method check for the segue you just created by its identifier. Cast the destination view controller and pass data to it by setting properties on the downcast view controller.
Setting an identifier for a segue:
Segues can be performed programatically or using button action event set in the storyboard by ctrl+drag to destination view controller.
You can call for a segue programatically, when needed, using segue identifier in the view controller:
func showDetail() {
performSegueWithIdentifier("showDetailingSegue", sender: self)
}
You can configure segue payload in the override version of prepareForSegue method. You can set required properties before destination view controller is loaded.
Swift
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetailingSegue" {
let controller = segue.destinationViewController as! DetailViewController
controller.isDetailingEnabled = true
}
}
DetailViewController is the name of the second view controller and isDetailingEnabled is a public variable in that view controller.
To expand on this pattern, you can treat a public method on DetailViewController as a pseudo initializer, to help initialize any required variables. This will self document variables that need to be set on DetailViewController without having to read through it's source code. It's also a handy place to put defaults.
Swift
func initVC(isDetailingEnabled: Bool) {
self.isDetailingEnabled = isDetailingEnabled
}
Why not pass the whole dictionary with all the contents from firebase to the new VC using prepare for segue?
And then store the dict in the destinationVC data model?
That should do the trick.
I have a table view populated with cells containing the user's friends. A cell, when selected, should pull up that friend's profile. However, while the profile view does show up, I don't know how to tell its view controller to load that friend's profile data. How do you have two view controllers communicate with each other in response to user action? Thanks in advance.
Let's have two view controllers:
destinationVC and sourceVC
Create optional variables in destinationVC to store values which you want to share between the VC's.
In the sourceVC
override prepareForSegue method
obtain the destinationVC using segue.destinationViewController and store the returned value in a variable, say destVC
initialise the optional variables of destVC with values from selected cell
you can obtain the selected cell by using tableview.cellForRowAtIndexPath(tableView.indexPathForSelectedRow())
get data from selected cell and assign it to destVC's variables
Then in the destVC
In the viewDidLoad method
Check if the optional variables are not nil
Use the values of variables to load/update the destVC.
Edit: Updated answer according to Mike Taverne's comment.
You need to set the "user" property of that "destination" view controller in your current view controller:
Set a selectedUser property in your current view controller:
class CurrentTableViewController: TableViewController {
var selectedUser: AnyObject?
...
}
Then when that friend's cell is selected, set the "selectedUser" property in "didSelectRowAtIndexPath":
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedUser = // get the user property depending on how you're defining your table cells in the first place
self.performSegueWithIdentifier("pushToUser", sender: self)
}
Next in your prepareForSegue method, define the destination view controller and set its "user" property from the "self.selectedUser" property:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "pushToUser") {
var userProfileTableViewController: UserProfileTableViewController = segue.destinationViewController as UserProfileTableViewController
userProfileTableViewController.user = self.selectedUser
}
}
Last, in the destination view controller (which in this case is UserProfileTableViewController) you can call your database queries, etc. using "self.user".
I have a UITableView which I have set up to go to a different VC when a row is selected by the user (the table only consists of one array). I want to pass the row index of the selected item. I am using didSelectRowAtIndexPath to set a variable named selectedCellIndex to the row index. However, since I also have the tableView set up to go to the next VC prepareForSegue fires off (or around the same time) as didSelectRowAtIndexPath. As a result the first time I select an item from the list the value sent is nil, after that I always get the previous value of the row selected. Any Ideas on how to make sure that the variable is set before the app transitions to the next segue without putting a pause?
Here is my code:
var selectedCellIndex:Int!
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
var indexPath = tableView.indexPathForSelectedRow() as NSIndexPath?
selectedCellIndex = indexPath?.row as Int?
}
//SEGUE
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "signature" {
let vc = segue.destinationViewController as SignatureViewController
vc.index = "\(selectedCellIndex)"
}
}
Thanks
You can get the selected index path from the table view directly using the indexPathForSelectedRow method. There is no need to implement didSelectRowAtIndexPath just to store the selected index.
The prepareForSegue: method is the only method where you should set/access variables that are necessary for a transition.