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)
}
Related
I have a root view controller - which is a simple page presented to the user. In this page, there is a UIBarButton that goes to the user profile page.
When the user is in its profile, he/she'll have a back button that will allow him/her to go back to the root view controller.
However, the root view controller is different for admins and clients (there is one standard view controller for admins and one standard view controller for clients).
How can I create two segues that are triggered by the 'Back' profile button? I mean, depending on who is currently logged in (an admin or a client), I would like to go back to their respective pages.
The client cannot go back to the admin's page and neither vice versa.
Is there any way to create these two segues? Or even another/better way? I have tried to do that using storyboard, but when I create the second segue, it deletes the first one linked to the button.
You cannot do that but there is other way for that, create two segue bwtween SenderViewController and DestinatrionViewController. After that set action for your button and perform the segue according to your requirements.
#IBAction func buttonAction(_ sender: UIButton) {
if condition {
self.performSegue(withIdentifier: "identifier1", sender: nil)
}
else {
self.performSegue(withIdentifier: "identifier2", sender: nil)
}
}
Going off of Nirav D's answer, use an if...else with the condition that they are an admin or client. But don't control+drag from the button itself, control+drag from the ViewController as seen in the images below.
you should handle it in your code.
#IBAction func backClick() {
if isAdmin /* check condition here */ {
// admin work
} else {
// normal user work here
}
}
Then let create segue from storyboard and give it an identifier.
If you want perform segue, let use
performSegue(withIdentifier: "identifier", sender: nil)
if you want go back.
dismissViewControllerAnimated(true, completion: nil)
Hope it help.
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
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
}
I would like to know if it is possible to assign two different unwind method at the same button. For example:
I have this views navigations:
Home->A->B
Home->C->B
A and C views navigates to B, but then I want to return to previous views using the same B view and controller.
It is possible?
I have been thinking about write assign unwind method to the button programmatically depending what view comes.
Thanks in advance
I'm sorry about my english, is not good.
Here's a Swift solution that worked well for me. The code below only works if you hookup your segues correctly in the storyboard and in code. Checkout this page for great explanations on setting up unwind segues.
In summary:
You're accessing the same view from multiple other views. So, when you segue to a view, you can pass the source view controller (the view that you're currently in) to a property in the view that you're going to.
In your view that you will unwind out of, you can check the property holding the info (the class) on where you came from, and then perform a segue based on what view it is.
The code: (using ex: Home -> A -> B or... Home -> C -> B)
Note: B is the view that will unwind to multiple different views.
In A or C: (code works the same way in both views)
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segueIdentifierInViewAthatGoesToViewB" {
let controller:B = segue.destinationViewController as! B
//the code below passes our current view controller class to a property in view B.
//So, view B will know what view we came from.
//In our example, we're coming from view A or C
controller.viewControllerNavigatedFrom = segue.sourceViewController
}
}
In B:
//setup an IBAction that will check the source view controller (that we passed when we segued to this view) and perform a segue based on where we came from. You can hook this up to a button or anything you want really.
//isKindOfClass(A) - "A" would be the name of your class
//setup a property to receive the view controller class where we are coming from
var viewControllerNavigatedFrom:AnyObject?
#IBAction func myButtonPressed(sender: AnyObject) {
if self.viewControllerNavigatedFrom!.isKindOfClass(A) {
//Unwind to view A
performSegueWithIdentifier("unwindFromBbackToA", sender: sender)
}
else if self.viewControllerNavigatedFrom!.isKindOfClass(C) {
//Unwind to view C
performSegueWithIdentifier("unwindFromBbackToC", sender: sender)
}
}
Although, question isn't very clear. But what I could understand is that you want to navigate back to the previous view i.e. B>C or B>A depending upon where user came from.
If so, then check the UINavigationController. It keeps track of the navigation history and automatically adds a back button. Kind of like the back button in our browsers.
Here is a tutorial, although a bit old: Link
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...