Adding a child view controller and changing its label - ios

I got a view controller named IntroViewController in my storyboard and I want to add this as a child to another view controller like this:
IntroViewController *introViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"View1"];
[introViewController.textLabel setText:#"test"];
[self addChildViewController:introViewController];
On the IntroViewController I've put a label named textLabel on it in the storyboard, if I run the program it works and shows me the view controller, but the text doesn't get changed. Any idea how I can fix this?

When you instantiate a view controller from a storyboard, the view is not loaded until it is actually presented on screen. At the point in your code you have posted introViewController.textLabel is nil.
One option you could do is add a property to your IntroViewController class and instead set that:
introViewController.initialText = #"test";
Then, inside -viewDidLoad of your IntroViewController the label will be instantiated so you can make the call:
[self.textLabel setText:self.initialText];
It is also worth noting that most of the time it would be recommended to have a view controller be the one to set values on the views it owns, rather than some other view controller.

Related

Go to another Viewcontroller

In my app, I need to go to another UIViewController with a button click, but when I did it in the new UIViewController it displays only what I set programmatically.
I used:
NewSubject *NewS = [[NewSubject alloc] initWithNibName:nil bundle:nil];
[self presentViewController:NewS animated:YES completion:nil];
"NewSubject" is the UIViewController I need to go too, however I want the computer to display also the stuff I set by the Storyboard.
Have you set in the Storyboard, in the NewSubject View Controller, in the third tab (Show Identity Inspector) the StoryBoard ID?
You should set it to some name, such as "NewSubject" and use it as follow:
NewSubject *NewS = [self.storyboard instantiateViewControllerWithIdentifier:#"NewSubject"];
[self.navigationController pushViewController:NewS animated:YES];
I want the computer to display also the stuff I set by the Storyboard.
If you're using a storyboard, -initWithNibName:bundle: is the wrong method to use. You can use UIStoryboard's -instantiateViewControllerWithIdentifier: method to create a new view controller that's defined in a storyboard, but the more typical approach is to have your button trigger a segue between the two view controllers.
Try this:
While editing your storyboard, control-drag from your button to the new view controller. A popup menu should appear that lets you choose how you want to transition between the view controllers -- push (push the new controller onto the top of the navigation stack), modal (present the view controller modally), etc. Pick the appropriate one.
In simple cases, you're done -- there's no need to write any code just to get the transition to happen. The segue takes care of creating the new view controller and performing the transition for you. However, you often want to pass some data from the existing view controller to the new one. If that's the case, implement -prepareForSegue:sender: in the existing view controller -- this method gives you a chance to pass whatever data you need. It'll look something like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// It doesn't hurt to check that it's the segue that you expect
if ([segue.identifier isEqualToString:#"MySegueIdentifier"]) {
NewViewController *newVC = segue.destinationViewController;
// This is your chance to set properties or call methods to pass data to the new view controller
newVC.foo = self.foo;
newVC.bar = self.bar;
}
}

Some code not executing in a method called from another ViewController

My problem
I have a standard UIViewController. With the press of a button, it loads a form sheet modal view controller. When dismissing this modal view with the press of a UIBarButtonItem I call a method by doing:
ViewController *main = [[ViewController alloc] initWithNibName:nil bundle:nil];
[main updateLabel];
In the method -(void)updateLabel in the main ViewController I'm setting the text of a label, but the label won't change. But I know the function gets called, because if I do a NSLog(#"Method call test); instead of label.text = #"Test" I can see the message in console.
What am I doing wrong? It must be the way I'm calling the method in the main ViewController, because I can easily change the label anywhere else.
What I want to do:
When dismissing a modal view controller, I want a method to be called in the main view controller, and in this case change the text of a label.
Thanks for your help!
You're creating a new instance of ViewController with that code, not getting a pointer to the one you already have.
If ViewController is the controller that presented the modal view, then you can get a pointer to it with,
ViewController *main = self.presentingViewController;
A better way to do this would be to use the delegate pattern.
https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/Delegation.html
The following is a design pattern suggestion
The modal view controller shouldn't know how to dismiss itself, that is the responsibility of the presenting view controller. After all, it could have been presented in many different ways (modally, popover, push navigation). Using the delegate pattern, the modal view controller would tell its delegate that it should be dismissed when the bar button item gets pressed. The delegate, which is the presenting view controller, would then dismiss the modal view and update the label mentioned in your question.

Unable to display view when I call it from a separate ViewController in iOS

I have a view controller in my application where on my screen I have a UIView that the user is required to tap on. When they do that, I want to call another viewController's view, and display it on the screen for the user. Unfortunately, I am having trouble displaying the view.
The name of my viewController that I am making the call from is called "MainViewController", and the ViewController whose view I wish to display is called, "NextViewController"
Here is my code from where I make the call:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"I was touched.");
_nextView = [[NextViewController alloc] init]; //this code is not being called
[self.view addSubview:_nextView.view]; //neither is this being called
}
Where _nextView is a property that I declare in the .h file of MainViewController.
This method is being called, but for some reason because I am able to see the log statements print to the output, but for some reason I am unable to call the lines after that. What am I doing wrong?
You shouldn't add the view of another view controller to your view without making that view controller a child view controller. If you just want a view, then set one up in a xib file and add it to your view as a subview. If you want to use a view controller, then you should present it modally, and dismiss it when you're done. This kind of situation where you want to gather some info from the user to use in your app, is an appropriate place to use a modal view controller. MainViewController should set itself as the delegate of NextViewController, and NextViewController should define a delegate protocol to send the data back to MainViewController.
To present it modally, do this:
_nextView = [[NextViewController alloc] initWithNibName:#"your nib name here" bundle:nil];
[self presentViewController:_nextView animated:YES completion:nil];
Are you using a Navigation Controller? Or Storyboards? One way of displaying another view controller would be like this:
[self presentViewController:_nextView animated:YES completion:^{
}];
A couple of things:
- If your NSLog gets called, then so do the other two lines you say do not.
- I assume you mean you want to display the other view controller on screen, not display the other view controller's view on the first view controller. These are two very different things, the second of which you wouldn't want to do.

My viewController doesn't show up right

in my iPad-app I am trying to present one of my views with a modal formsheet-style.
Here's some code:
-(void)present
{
SecondViewController *modal = [[SecondViewController alloc]init];
modal.modalPresentationStyle = UIModalPresentationStyleFormSheet;
[self presentModalViewController:modal animated:YES];
}
I am using Storyboard, and I have put stuff like a textView and toolbars in the view I'd like to show. I have set the right class in Identity Inspector, and in the class-files I have checked that it's the right view appearing with putting NSLog(#"Right view");
When calling the void present, a view is appearing, but only as a dark-white square. Nothing og my content from Storyboard is in it, I even tried changing the background color of the view and the textView to see if something was just outside the square, but the whole thing stayed white. It feels like it's not using the view I created in storyboard, but I have set it to the correct class, and the NSLog gets printed out when calling it. I have not connected the two views in any way in Storyboard, the SecondViewController is just floating around, so that might be the problem? The button that calls for -(void)present is created programmatically, so I can't ctrl+drag it to the button either.
Why is it showing an empty version of my class?
In the "Identity Inspector" set a "Storyboard ID" for your ViewController, and then present it like this:
-(void)present
{
SecondViewController *modal = [self.storyboard instantiateViewControllerWithIdentifier:#"myStoryboardID"];
modal.modalPresentationStyle = UIModalPresentationStyleFormSheet;
[self presentModalViewController:modal animated:YES];
}
And if you're using iOS6, presentModalViewController:animated: is deprecated, so use this:
-(void)present
{
SecondViewController *modal = [self.storyboard instantiateViewControllerWithIdentifier:#"myStoryboardID"];
modal.modalPresentationStyle = UIModalPresentationStyleFormSheet;
[self presentViewController:modal animated:YES completion:nil];
}
Your problem is that you're assuming the program will intrinsically know where to find the, already laid out, view for this controller when that's simply not how storyboards work. The code you list about will create a view controller, but without an associated view it will simply show as a black square.
There's a few ways to solve your dilemma:
Add the modal transition as a segue in the view controller, this would be the simplest way and is what iOS storyboards expect you to do.
Move the view from the storyboard to an external .xib and call the initWithNibName:bundle: method to load this as your view controller's view. This is the best solution if you just want to programmatically load the view.
Load the view from your storyboard programmatically with the instantiateViewControllerWithIdentifier: method, this is probably a bad idea as it goes against the design of storyboards.
I can elaborate on those if you want.

Programatically adding a tableView, viewDidLoad not called

I would like to use my viewDidLoad function in my tableViewController.
How can I make viewDidLoad run in my controller?
tableViewController = [[TableViewController alloc] init];
UITableView *tableView = [[UITableView alloc] init];
tableViewController.view = tableView;
....
From Apple documentation:
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
So you can try to instantiate it from NIB or overwrite the loadView method. Another step from Apple documentation:
If you cannot define your views in a storyboard or a nib file, override the loadView method to manually instantiate a view hierarchy and assign it to the view property.
viewDidLoad will be called when the view is actually loaded, which will happen after you present your view controller, by, e.g.:
adding it to a navigation controller,
adding it to a tab bar controller,
presenting it modally.
This is the missing bit in your code. If you explain how you would like to present your view controller, I may help further. Also, have a look at this: Presenting View Controllers.
(I assume the fact that you tried to override the view property of your table view controller was just an attempt "to make things work" -- but you do not need to do anything about that, the view controller will be correctly set up with a table view inside of it).
tableViewController = [[TableViewController alloc] init];
tableViewController.tableView // This is your newly generated tableview
viewDidLoad will be called after you assign the tableView to another parentview

Resources