Passing data to another UIViewController with buttons - ios

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.

Related

How to pass a different url to the next VC with prepare for segue?

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.)

Swift dynamic view based on cell tapped in previous table view

I have a table view with a list of events. I now am trying to create a dynamic view that can show details about all of those events based on the event tapped on. Two questions I have are how do I create a generic segue that I can use for any table cell to go to the same view, and then in that view how do I access the cell that brought the user to the view?
You would use didSelectRowAtIndexPath. First, create a variable eventToPass of type Event (or whatever your class is called) on your ViewController. Then, you should get the object that represents your data, then pass that to your new UIViewController. Something like:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let event = eventsArray[indexPath.row]
self.eventToPass = event
self.performSegueWithIdentifier("EventSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "EventSegue") {
var detailVC = segue.destinationViewController as EventDetailViewController
detailVC.event = eventToPass
}
}
This assumes that you have a ViewController called EventDetailViewController that has a property called event. From here, you can access any of the event's details on your new ViewController.

Using segues to populate tableView with data from Parse

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.

how to display a new tableview from user selecting row in tableview swift

I am trying to figure how to segue to a new view when the user selects a certain row in the current tableview. I am thinking this will be done by the didselectrowatindexpath method but can not figure out the logic of how it will work. I would like it to display a view with the specific courses in the subject the user selected. I think this will use an array? I would appreciate any help here thanks.
Yes, you're right, you can do this be responding to didSelectRowAtIndexPath.
You can have a view controller as your table view delegate that implements these methods:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if let thing = self.things.objectAtIndex(indexPath.row) as? Thing
{
self.performSegueWithIdentifier("OpenThing", sender: thing)
}
}
Where "OpenThing" is a segue defined in my storyboard.
Then I have overridden the prepareForSegue method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "OpenThing"
{
if let controller = segue.destinationViewController as? ThingViewController
{
if let thing = sender as? Thing
{
controller.thing = thing
}
}
}
}
This is a contrived example of having an array of "Things". I access a thing by row index then segue to the next view controller, providing the thing that I want to display.

Swift - Tell TableViewController what data to populate with

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".

Resources