Pardon me for beginner's question.
I know I can switch to another screen (ViewController) like this
self.performSegueWithIdentifier ("SecondViewController", sender: self)
but I can't seem to find where to assign my 2nd screen the id, I just find Storyboard ID, is that it?
I've already tried, only received a crash with the following error:
Receiver () has no segue
with identifier 'SecondViewController'
Any idea? thanks
Segue Identifier is not the same as storyboard ID, storyboard ID used when you want to create a View Controller based on that specific storyboard -and it has to be unique, unlike the segue identifier-.
If you already know how to create a segue, you can skip this part.
Adding a segue between two viewControllers:
From the Interface Builder, press the ctrl and drag between the two View Controllers that you want to link (make sure that you are dragging from the view controller itself, not the its main view). You should see:
Choose the "Show" -for instance-, the output should look like this:
As shown above, the arrow that surrounded by the red rectangle is the segue.
Additional note: if you selected the "Show" option, you have to embed your first view Controller in a Navigation Controller (select your first viewController -> Editor -> Embed In -> Navigation Controller), the output should looks like:
Because the "Show" means pushing into a navigation controller stack.
Assigning an identifier for the segue:
Select the segue, from the attribute inspector you'll see "Identifier" text field, that's it! make sure to insert the exact same name that used in performSegueWithIdentifier.
If you don't know where to find the attribute inspector, it is on the top right looks like:
Furthermore:
For adding multiple segues from one View Controller, follow the same process (ctrl + drag from the first controller to each other View Controller), the output should looks like:
In this case, you might face the issue how to recognize which segue has been performed, overriding prepare(for:sender:) method is the solution, you can make the checking based on the segue identifier property:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "firstSegueIdentifier") {
// ...
} else if (segue.identifier == "secondSegueIdentifier") {
//...
}
}
which would be the name that you have added to the segue in the storyboard.
In your code
self.performSegueWithIdentifier ("SecondViewController", sender: self)
the string "SecondViewController" is looking like storyboard id . At the same place you have to write the segue identifier , not storyboard id .
Follow the Screenshot and assign segue identifier name by clicking on the segue on right top bar field. you can do like this
self.performSegueWithIdentifier ("WriteSegueIdentifierName", sender: self)
Similar to the answers provided, here's what it would look like in Xcode 12:
Select the segue link in Main Storyboard view
Navigate to the Attribute Inspector and add an Identifier (if one does not exist)
Add the Identifier to your code. Done!
When you link a View controller to another View controller in the storyboard, in the link between them you need to assign a segue identifier i.e "SecondViewController" only then your code will work.
Alternatively, you can also show another view controller through storyboard id using self.storyboard.instantiateViewControllerWithIdentifier("//storyboard id of that view controller") and then either use present/show view controller.
You can initiate viewController like this:
let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Login")
self.present(viewController, animated: false, completion: nil)
Show Xcode screenshot
Click on Present Modally segue label... and on the Attributes Inspector input Identifier
Related
I am using prepare for segue to set a dictionary variable in another view controller. But the issue is the view controller opens the map without the data. How can I make sure I go to next view controller only after the dictionary variable data has been set.
Here is my code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showMapSegue"
{
if let mapVC = segue.destination as? MapVC
{
if vendorStoreKeys.count != 0{
mapVC.vendorStore = vendorStoreKeys
}
}
}
}
But the vendor store array in next view controller is still empty when the controller is visible. It sets the data after some time but at that point I am unable to reload that view controller so I need to make sure I don't go to next view controller before the mapVC.vendorStore variable is properly set.
I was able to resolve the issue. Prepare for should have set the data before calling and it was. Issue was I actually forgot to remove the segue in the storyboard which was directly going from the button to the new view controller. So here is what I did
Removed the segue which was going directly from the collection view cell button to the next story board
Created a new segue from the top of the view controller to the next view controller
Named that segue "showMapSegue"
Build and Run. I got the data successfully in the next view controller. Hope it helps.
How can I change the identifier name of a specific segue programmatically?
I found this way but didn't work with me:
SWrevealviewcontroller : Switch slideout menu direction from left to right pragmatically
Edit:
I have menu SWreavealviewcontroller and I want it to be from left in case of English language and from right in case of Arabic language.
You can't change segue names programmatically. Because a segue defines a transition between two view controllers in your app’s storyboard file and you can rename it in your storyboard.
You can define more than one segues between your view controllers and call segues programmatically like this:
performSegue(withIdentifier: "yourSegueID", sender: nil)
For your problem:
You can create two segues between your view controllers, and give
two different segue identifier names to them (eg. englishSegue and
arabicSegue).
Create a variable for your segue identifier. (You will use it to
select which of your segue should be triggered.)
Control your language in your view controller (eg. in your
viewDidLoad function or where you should control it)
programmatically and set your language variable as English or Arabic.
After that you can trigger it anywhere you want it. For example in a
button click:
if (yourIdentifier == "English") {
performSegue(withIdentifier: "englishSegue", sender: nil)
} else if (yourIdentifier == "Arabic") {
performSegue(withIdentifier: "arabicSegue", sender: nil)
}
I simply want to know how to segue to a new view controller in a new storyboard without having to create the new view controller programmatically.
The Scenario:
I have one view controller that's created entirely in code and the system thinks I'm in Storyboard A. I want to segue from this view controller to another view controller that's contained on Storyboard B.
I could create a segue attached to a storyboard reference (which is a great suggestion) if this view controller was created with Storyboard. But it's in code, so I can't do this.
My other option is to make the next view controller be totally created in code so that I can present it without using segues. That's a pain, but will work.
My third option is to initialize the new storyboard in code, initialize the new view controller in code using a storyboard identifier, and then use the navigation controller to segue to it.
If there are other options I'm not aware of please include them below!
This piece of code allows you to segue to any viewController anywhere in your application while still being able to build your viewController with storyboard.
func settingsButtonPressed(sender:UIButton) {
let storyboard = UIStoryboard(name: "AccountLinking", bundle: nil)
let linkingVC = storyboard.instantiateViewControllerWithIdentifier("AccountLinkingTable")
self.navigationController?.pushViewController(linkingVC, animated: true)
}
So many hours saved thanks to this little function.
I would urge anyone reading this to take a look at the Storyboard Reference introduced in Xcode 7 to achieve this instead of loading the storyboard programatically.
You can override the below function to override the segue call.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var destinationController = segue.destinationViewController
}
In Swift 2, Xcode 7.1
As the image above, TabBarController will be the main view. Anonymous user can go to the home tab, if they click on the "Me" (Profile) tab, I want the app will pop up the new login segue (navigation controller). User need to login 1st before they can go into the "Me" tab.
Currently I have override the TabbarControllerDelegate in the TabBarController class, which as below (I use Parse, so user = PFUser.currentUser(), Parse will cache the user):
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
if (viewController is MeViewController && user == nil) {
print("login \(viewController)")
// How could I go to the Login Segue from here?
return false
} else {
return true
}
}
How could I achieve my goal from here? Or any better advice? Btw, I am not able to use performSegueWithIdentifier with the TabBarController class unless I use it within the ProfileViewController class (UIViewController) to achieve it. But if I did that, the app will display the view in 'Me' Tab first then go to the 'Login' segue, which is not what I wanted
It will be great thanks for any advices
If you want the user to not be able to go to me before login, you can just do a check with a static bolean which will be initialize in app delegate.
Then if the bolean is set to false (default value), you can invoke the your login popup.
No point here to perform a segue, just put an identifier on the view in the storyboard (identity inspector => storyboard id) and then you can invoke this particular view of the storyboard like this :
let SB = UIStoryboard(name: "MyStoryboard", bundle: nil)
let controller = SB.instantiateViewControllerWithIdentifier("MyId")
self.presentViewController(controller, animated: true, completion: nil)
Segues are only for views which are linked to each other, i personnaly almost never used them.
I recommend that you make the login UINavigationController segue come directly from the UITabBarController instead of on the "Me" controller. This is because you can't modally present your login controller through the "Me" controller if its not on the screen.
Give the segue an identifier (eg. "my-identifier"):
Click on the segue in the storyboard editor and fill in the identifier field in the right sidebar.
After this is configured correctly, the following code will perform the login segue (note the use of tabBarController since you should have the segue configured from the UITabBarController:
tabBarController.performSegueWithIdentifier("my-identifier", sender: self)
I encountered a crash while testing my app. The following image is my storyboard:
I have the code in View Controller:
#IBAction func unwindToHomeScreen(segue:UIStoryboardSegue) {
}
The view of "Add new Item" have a "Cancel" button, I controlled-drag it to the "Exit" icon at the top and link to unwindToHomeScreen, it works fine.
The "Add new Item" has a class AddTableViewController and the code I wrote inside:
#IBAction func save() {
// Execute the unwind segue and go back to the home screen
performSegueWithIdentifier("unwindToHomeScreen", sender: self)
}
I controlled-drag the "Save" button to the func, but the app crash when I click the button
I can use dismissViewControllerAnimated(true, completion: nil) instead, but I just wonder why performSegueWithIdentifier can't work?
I read the code at dropbox.com/s/hpybgg9x67rtqng/foodpinstatictable.zip?dl=0 and try to make one and using performSegueWithIdentifier like this example for practicing, I didn't see the segue identifier at her, what is the difference?
You haven't actually given that segue an identifier. unwindToHomeScreen is a function that you can call; what you're looking for is your segue identifier, which is set in Interface Builder like this:
In this example, I have a button wired to the next view via Interface Builder like you describe ("Interface Builder") and a button that is wired to this IBAction in my view controller ("Programmatically"):
#IBAction func goToNextView(sender: UIButton!) {
self.performSegueWithIdentifier:("go", sender: self)
}
In any case, what you're missing is the actual identifier, which can be set in the attributes of a segue created in Interface Builder.
Swift 4:
Sometimes we must clean the build folder and then try again.
Worked for me after ctrl-dragging the new segue and giving it a name, then using it programatically as:
performSegue(withIdentifier: "goToMyNewViewController" , sender: self)
I found that because I renamed my view controller, I needed to delete and recreate the segue.
A possible issue with iOS 12 and earlier (iOS 13 seems not to suffer from the same issue) might come from the fact that performSegue(withIdentifier:,sender:) is called from the view controller viewdidLoad() callback.
You absolutely must invoke it from the viewDidAppear(_ animated: Bool) callback in order to avoid the question-mentioned crash.
That will certainly save hours of hair-puling…
in my case reorder the Embed in
Tab bar controller
Navigation controller
vc (contains button - tapping button initiates a "show, e.g. push" segue)
Too fix the title in the navigationBar
I had the same issue.
All I did was:
I selected the segue indicator in the storyboard.
Deleted it.
Then created a new segue with the same identifier. Boom, it works.
I had it all wired up correctly. It was just that the viewController I was segueing from, was NOT instantiated from the storyboard. I had it instantiated pragmatically.
I initially had it written as:
let vc = DeviceVC()
Had to change it to:
let sb = UIStoryboard(name: "Main", bundle: Bundle(for: DeviceVC.self))
let vc = sb.instantiateViewController(identifier: "DeviceVC") as! DevieVC
for me --> click on the relation-arrow between view controllers and then select attribute inspector, there is identifier give name and select push class done...