What exactly does segue.destinationViewController do? - iphone

Hey guys what does this line of code do?
AddRoleTVC *addRoleTVC = segue.destinationViewController;
I know the first part, with the AddRoleTVC *addRolveTVC, but i don't know what the segue.destinationViewController part does, i have found many different answers I'm just not sure which is the right one. Thanks in advance!

In here the segue.destinationViewController points to the ViewController we are going to navigate to and is of type ‘id’.
Because we know where we are navigating to i.e in this case AddRoleTVC , we can treat segue.destinationViewController as if it were our AddRoleTVC and call methods on it.
That’s how we pass data from one VC to another through the segue by calling set property methods directly on our new ViewController i.e addRoleTVC.

A segue is a transition from one view controller to another. The destinationViewController is "another", the one being transitioned to.
The typical use of this property is to do some extra setup on the destinationViewController before the segue happens. The from VC gets the message - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. Then it can grab segue.destinationViewController and do extra init, like giving it it's model.

Related

Black screen with viewDidLoad after if else statement

I want my app to check at start conditionaly if a variable is correct or not. Based on that it should either go to an intro screen (where he can select a variable in my case select a team) or it should start the main view. After searching i found this code and edited it. But there still seems to be problems. First of all I dont have two identifier. The Intro has one but not the main view. My main View is called WeatherViewController and the Intro screen is called FirstScreenViewController. I also added a picture of my Main.storyboard.
I also googled a lot about conditional UINavigationController but I can only understand with a video and did not found a video about it.
I tried to use the code from here.
var id = hello ? "goToIntro" : "???"
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let WeatherViewController: UIViewController = mainStoryboard.FirstScreenViewController(withIdentifier: WVC has no identifier??) as UIViewController
self.window?.rootViewController = WeatherViewController
self.window?.makeKeyAndVisible()
if hello {
self.performSegue(withIdentifier: "goToIntro", sender: self)
} else {
/here nothing should happen. It should open the Main View
self.performSegue(withIdentifier: "???", sender: self)
}
Note: This answer was referring to the original question (before any edits) that was attempting a segue inside loadView().
You're supposed to manually create your controller's view in loadView. You're currently doing nothing, hence the black screen. Furthermore, if you are using a Storyboard or a xib for managing this controller you shouldn't be overriding loadView at all.
Having said that it might be a better idea to move this branching logic a step back, to "something" (a container controller like a UINavigationController or a custom one, or even directly setting the root controller of your window if it makes sense) that will present (or set) A or B based on some condition and thus avoid to load this controller altogether (have in mind that in your code, the controller is initialized, it will be part of the hierarchy and all the lifecycle methods will be called even if you segued directly to another one)
Finally, if you decide for some reason to override loadView you don't have to call viewDidLoad yourself, the system will call this method.

PushViewController shows Black Screen

i have a problem with my App.
I´m not an experienced programmer, so maybe it´s just a simple solution. I thought this problem exists because i´m just trying things and play with my app so i made a new App and there´s the same problem.
When i push to a ViewController with navigationController?.pushViewController(PinkViewController(), animated: true).
I´m getting just a black screen. If i have a code like
Label.text = "String in viewdidload of the PinkViewController(). I get the following error at this line of code:
fatal error: Unexpectedly found nil while implicitly unwrapping an
Optional
I searched the web and i didn´t find any solutions for this problem. I hope you can help me.
The reason why it crashes is that your label is probably defined as an #IBOutlet that is connected to a UILabel in your storyboard's PinkViewController. However, when you instantiate PinkViewController with an empty constructor, you're not "using the storyboard-way" and your label outlet (which is non-optional, because it's likely to have an exclamation mark there) could not have been connected to the storyboard instance of your view controller.
So what you should do is one of these options:
If you defined PinkViewController in the storyboard, you'd have to instantiate it in a nib kind of way, for example:
In your Storyboard, select the view controller and then on the right side in the Identity Inspector, provide a Storyboard ID. In code you can then call this to instantiate your view controller and then push it:
let pinkViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "yourIdentifier")
Even better, you create a Segue in the storyboard by control-dragging from the current VC to PinkViewController. There's lots of tutorials for creating Segues online. Don't forget to provide an Identifier for the Segue in the Storyboard, if you want to trigger it programmatically. This can be done by calling
self.performSegue(withIdentifier: "yourIdentifier", sender: nil)
If you want to trigger that navigation upon a button click, you can even drag the Segue from the button to PinkViewController, that way you wouldn't even need to call it in code.
If you defined PinkViewController programmatically only (by creating a class named like that which conforms to UIViewController), you might wanna instantiate it with PinkViewController(nibName: nil, bundle: nil) (notice the arguments instead of an empty constructor) and then push it with your provided code.
Hope that helps, if not, please provide further code / project insight.

Come back to the tabBarController, swift

Currently on my viewController : Upload, my button send the data to my database only if all the information are filled out, and I come back to the preview view (table View) with :
self.navigationController?.popViewControllerAnimated(true)
I would like, if it is possible, to come back to my main view on the tabBarController. I tried many things, like directly on the storyboard with Present modally segue to "TabBar controller", but I come back to the TabBar without sending my data to the database and without checking in the information are filled out..
How can I do it?
Thanks!
UITabBarController has a property selectedIndex with which you can switch the selected tab. So on completion after dismissing the UploadViewController you can run:
self.tabBarController?.selectedIndex = 0 // Index to select
It would probably be best to create a delegate for your UploadViewController to fire a function to do all the work in your previewVC on API call completion.
(Super late response...in case someone has similar questions, presumably in later version of Swift, such as mine which is Swift 5, iOS 13.2). Steps:
Be sure to set an id for your UITabBarController storyboard, e.g. "TabBarViewController"
Next, add the following to an action that has already been connected to a button:
let ID_TABBAR = "TabBarViewCOntroller"
#IBAction func returnToTabbar(_ sender: Any) {
let tabBarController = self.storyboard?.instantiateViewController(identifier:ID_TABBAR) as! UITabBarController
self.navigationController?.pushViewController(tabBarController, animated:true)
}
Referenced from one of the responses from this post.
Update: In case your Tab Bar View Controller also happens to be the root view controller, the two lines of the code in the returnToTabbar method above can be:
self.dismiss(animated:true, completion:nil);
self.navigationController?.popViewController(animated:true);
(ref.: See answer here, for Swift4 but works just fine in Swift5)

Using segues and nsnotificationcenter

I have 2 viewcontrollers and I want to send a notification out from one to the other and have a label changed based on the name of the notification (pressing a UIButton). I just started using segues and found they are a very useful way to get from one view to another. The problem I am facing is that using a segue (modal at the moment), the second view controller is not receiving the notification. I believe that segues release and create new view controllers when used, not sure. Is there any way around this?
Thanks!
I think using NSNotification is not the right method for passing data from one VC to another. Like Rog said, use prepareForSegue and use a property on the destination VC:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Always check to make sure you are handling the right Segue
if ([segue.identifier isEqualToString:#"mySegue"]) {
MyOtherViewController *movc = segue.destinationViewController;
movc.myProperty = #"MyValue";
}
}
Use prepareForSegue for going-to a segue, and use the delegate pattern for coming back. Within prepareForSegue, set the originating viewController as the delegate of the destination viewController. When returning, have the destination viewController call it's delegate (the original viewController) for whatever method you implement.

Xcode 4.2 & Storyboard, how to pass data between views? Existing code error

I'm trying to learn how to pass data between views. Say set a label in the second view from text entered into a text field on the first view. I basically have tried making a string in the second view and then when switching from the first view to the second I set a string in the second view. Then when the second view loads its sets the text of a label to the same string. I NSLog right before and after the transition, before its fine, but when the second view loads it string gets erased. I'm not sure why this isn't working. Here is my project: http://www.mediafire.com/?83s88z5d06hhqb5
Thanks!
-Shredder2794
From my book (http://www.apeth.com/iOSBook/ch19.html#_storyboards):
Before a segue is performed, the source view controller is sent prepareForSegue:sender:. The view controller can work out what segue is being triggered by examining the segue’s identifier and destinationViewController properties, and the sender is the interface object that was tapped to trigger to the segue (or, if performSegueWithIdentifier:sender: was called in code, whatever object was supplied as the sender: argument). This is the moment when the source view controller and the destination view controller meet; the source view controller can thus perform configurations on the destination view controller, hand it data, and so forth.
(Of course another solution is "don't use a storyboard". Then the first view controller creates the second and can hand it data then and there.)
The reverse problem is much trickier; look at the Utility Application template for an example of how to use the delegate pattern.
StoryBoards are ready made things where you can reduce a lot of code you write.So consider controller A & B on storyboard.
Now for passing data From A to B you can connect them with a segue name its identifier and then you can use delegate methods in A as:
//This method gets called before transition from A to B.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"THE IDENTIFIER YOU NAMED"])
{
id *objectOfController_B = [segue destinationViewController];.
objectOfController_B.lblTextDisplayOfA = //Something...
}
}
Now You can Explicitly transition it by using button in controller A.
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"THE IDENTIFIER YOU NAMED" sender:sender];
}
So I guess you can try experimenting on this and you will get it how and when transition occurs with segue.
Hope this helps.
There appear to be more than a few things to explain. I think working through a few tutorials will give you the answers you need. See http://www.raywenderlich.com/tutorials
i've asked more or less the same question a few weeks/month ago. there were some very good answers, especially the one from zoul, who built a demo project that will show you how to create a factory pattern application that will provide the views with the needed objects.
my question can be found here: iOS: Initialise object at start of application for all controllers to use and have a look at the answer from 'zoul'. it got me through this problem =)
good luck trying it out =)
sebastian
I spent "countless hours" my self trying to find a way to pass data and understand delegates with no comprehension and very little success. This video did something that all the other references I checked didn't do : keep it as simple as possible while clearly showing what was needed. Thank you so very much Mr Rob Smythe. http://www.youtube.com/watch?v=XZWT0IV8FrI
Have a look at this: http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
Delegate pattern is a common way to achieve what you are trying to do.