my Storyboard looks like:
User can go directly from the 1st screen to the 4th. The fourth screen contains tableView, with XIB cell design. I want user to be able to tap on a cell and get to the 3rd screen and send some data with that. I know this should be done in didSelectRowAt. But is it even possible?
Yes it is possible.
Create a segue. In your storyboard, ctrl-drag from the first button on top of your 4th screen to anywhere on your second screen. You should see a new segue created in your storyboard.
Give the segue an id. Click on the newly created segue, in the right panel, set the indentifier attribute under the Indentity Inspector tab.
Perform the segue. In your didSelectRowAt, add the following line:
self.performSegue(withIdentifier: "THE_ID_YOU_ASSIGNED_IN_STEP_2")
Send data to the destination segue. In your screen 4 view controller, add the following function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "THE_ID_YOU_ASSIGNED_IN_STEP_2" {
if let destinationVC = segue.destination as? YOUR_SCREEN_3_VC {
// Send data to your VC, such as assigning values
}
}
}
Related
I have two buttons - "Ok" and "Delete", and the "Ok" unwinds the segue to the last ViewController.
I want the "Delete" button to fire up the same unwind segue, but to do some action beforehand. (In my case, delete info from Firebase).
How can I combine both an action and unwind segue ? I tried calling PerformSegueWithIdentifier function but it didn't work.
Create a second unwind segue by control-dragging from your Delete button to the Exit icon. You can even use the existing #IBAction in your destination viewController. Give this segue an identifier (select the segue in the Document Outline view and set the identifier in the Attributes Inspector) such as "deleteSegue" and then in prepare(for:sender) check for the identifier and delete the info from Firebase.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "deleteSegue" {
// delete data from Firebase
}
}
Follow up question from the comments:
I want to perform an action BEFORE unwinding the segue - I want a
popup to ask the user if he really wants to delete the item. only
after that I want the item deleted and segue unwinded.
Instead of wiring the unwind segue from the Delete button, wire it from the viewController icon at the top of the VC to the Exit icon. Still give it the identifier and then call performSegue(withIdentifier: "deleteSegue", sender: self) when you want to perform the segue.
I have a TableViewController embedded in a ViewController. My UITableView has toggles. When one of these toggles are toggled I need my number on the ViewController to increase by 1. The issue I am having is not being able to get the text to change. I have supplied a screenshot to help better illustrate.
What I have tried doing is setting a variable var colorViewController: ViewController? in the TableViewController and then trying to set the text from there using colorViewController?.displayNumber.text = screenCount when toggling a toggle. screenCount is the variable that increasing as the toggles are toggled.
How are you setting your colorViewController variable?
You need to set it to the current instance of your ViewController in your ViewController's prepare for segue.
First, you'll need to give the embed segue an identifier. Select the segue in the storyboard and give it an identifier, say ColorPickerTableViewControllerSegue.
Then handle this segue in your ViewController (this is Swift 3 code):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ColorPickerTableViewControllerSegue" {
if let colorPickerTableViewController = segue.destination as? ColorPickerTableViewController {
colorPickerTableViewController.colorViewController = self
}
}
}
I have implemented the SWRevealViewController into my app to give my app a nice side menu. My main (home) screen for the app is TableViewController.swift - this is also the only place you can access the side menu from. The side menu all works perfectly. Here is an image to show what it looks like:
The 5 options you can see in the menu, are created in a tableView I want them to all link to other view controllers. I have currently achieved this using the method they showed in the tutorial for this side menu, which is to create a segue of reveal view controller push controller. This all works.
The problem
When you press one of the options, It reveals the new view controller as the sw_front, therefore, I have lost access to the main (home) screen. For example, the VC linked to the first option 'Films I want to see' is just a plain green VC. The image below shows what happens after I have pressed that option and then tried to go back:
So you can see, the VC that appears at the front is no longer my main (home) screen.
I'd like to know is there away I can set this up so when you press an option in the side menu, it opens up the new VC over the top of the side menu, so when you close down that VC, it still shows the side menu open with the Main (home) screen in front.
I hope that makes sense. Please ask if you need to see any of my code.
I managed to find a solution!
I first created my 5 new view controllers (one for each option in the side menu)
I then linked each cell to it's view controller by creating a 'Show' segue. So my storyboard now looked like this:
I created a segue identifier for each segue.
Then in my sideMenu.swift file, I added the following:
Created variables to store the identifiers for the segues.
// Mark:- Sets the side menu segue identifiers
let smOption_One = "toFilmsIWantToSee"
let smOption_Two = "toSearchForAnyFilm"
let smOption_Three = "toMeetTheTeam"
let smOption_Four = "toContactUs"
let smOption_Five = "toTermsOfUse"
I then added the didSelectRowAtIndexPath method, and added performSegueWithIdentifier for each of my segues.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier(smOption_One, sender: indexPath)
self.performSegueWithIdentifier(smOption_Two, sender: indexPath)
self.performSegueWithIdentifier(smOption_Three, sender: indexPath)
self.performSegueWithIdentifier(smOption_Four, sender: indexPath)
self.performSegueWithIdentifier(smOption_Five, sender: indexPath)
}
And finally, added the prepareForSegue method. Inside this method I did a check for each identifier, and then segued to the destinationViewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == smOption_One {
segue.destinationViewController as! FilmsIWantToSeeViewController
} else if segue.identifier == smOption_Two {
segue.destinationViewController as! SearchForAnyFilmViewController
} else if segue.identifier == smOption_Three {
segue.destinationViewController as! MeetTheTeamViewController
} else if segue.identifier == smOption_Four {
segue.destinationViewController as! ContactUsViewController
} else if segue.identifier == smOption_Five {
segue.destinationViewController as! TermsOfUseViewController
}
}
This perfectly creates a segue to the correct view controller, depending on which option I press, and presents it over the top of the side menu, so when I dismiss that view controller, it still shows me the side menu, and therefore allows me to get back to my main screen.
Not sure if there is an easier way of doing this, but it certainly works how I needed it to. Written in Xcode 7.2 with Swift 2.
Currently developing a small ios app in swift, I have populated a collection view cell with data from a .plist, each cell has a title and button, what i'm wanting is to segue to multiple view controllers in the storyboard depending on the segue identity once the button is pressed. For example if the segue has the id set as food, i want it to navigate to the view called food?
or if it is easier for the segue to pull the title from the cell then navigate to the view with the same title as the cell?
ill try and explain in code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "food"
{
//then navigate to the view controller called food
}
else if segue.identifier == "drink"{
{
//navigate to the view called drink
}
}
If food, drink or any other items have their own unique view in storyboard this is achievable.
You can assign a string to each button in UICollectionView and check which item in the collection was tapped and do a performSegueWithIdentifier: with button string.
performSegueWithIdentifier("toComments", sender: self)
Then prepareForSegue: method to pass data. Do another if for drink.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toFood" {
let ExchangeViewData = segue.destinationViewController as! FoodViewController
ExchangeViewData.foodMenuToShow = foodMenuID //This can be anything that you get your food items.
}
}
You can't do what you are asking for. A segue identifier is what determines which view controller gets invoked by the segue. If you want to go to a different view controller, invoke a segue with a different identifier. By the time you get to prepareForSegue it's too late. The segue to a specific view controller is already in progress.
You should explain what it is you're trying to do and we can help you solve your problem rather than trying to fight the APIs and do something that's neither possible nor appropriate. (Your question is an example of an "XY problem".)
I have a registration view controller. In it I process the input provided by the user soon as he clicks on the register button. This button in the view is connected to an IBAction where I validate the input provided.
How is t possible to trigger the segue and pass the data within the IBAction (not override prepareforsegue) to the next view controller? If the validation fails it shouldn't attempt to execute segue but rather stay on same view to display validation errors.
Thanks for support. The question has been asked in different ways before surely but I wasn't able to find a good combine of segue in ibaction and passing data too.
You can create a segue from one view controller to another and can put a check in your button's IBAction, like this:
if (validationPasses)
{
self.performSegueWithIdentifier("segueIdentifier", sender: self)
}
And if you don't won't to override your prepareforsegue, you can pass the data using delegates.
However, by overriding prepareforsegue, you can pass data to your next view controller like this:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "segueIdentifier") {
// pass data to next view controller
let vc : NextViewController = segue!.destinationViewController as NextViewController
vc.someVariable = someValue
}
}
Here NextViewController is your next viewcontroller, change its name to your next view controller and in this view controller define variable to whom you want to pass value, in this case it is someVariable