I am using XCode 4.4 and making an app with storyboard.
I want to switch to another view in a method of a view.
I want to achieve the same functionality as switching
view on storyboard by modal,inside the method.
So far I am using the following code:
-(IBAction)xplus:(id)sender
{
x++;
if(x>30)
{
ViewController_2 *viewControllerx = [[ViewController_2 alloc] init];
[self presentViewController:viewControllerx animated:YES completion:nil];
}
}
When the view is supposed to change ie when x becomes greater than 30
a Black Screen appears instead of the required view. I personally think my code is correct but why it shows a black screen?
How can I to achieve the same functionality as switching view on storyboard by modal,inside the method ?
Your method is not working out probably because you are not not using the .xib file with the view controller that you want to go to and using storyboard.
Anyways let me give you an easy and efficient method to perform the task.
Step 1: Go to storyboard of your project and click on the View Controller to which you want to go in your method i.e. ViewController_2.Click on the inspector icon(It is the 4th one). In the identifier field type a name eg: second.
Step 2: Use the following lines in your method to create a instance of ViewController_2 using the initiateViewControllerWithIdentifier method and to modal to it.
ViewController_2 *v2=[self.storyboard initiateViewControllerWithIdentifier:#"second"]; [self presentModalViewController:v2.animated:YES];
Now the app will go to(create instance of) the ViewController having the same Identifier as the one given as argument i.e. second.
Related
I am trying to make a tabbed application in Xcode that allows the user to take a photo and edit it on the FirstViewController class and when they are done display it on the SecondViewController.
When I started the project, Xcode automatically made the two viewControllers for me in the storyboard. What I need now is to find the instance of the second viewController that was generated so I can call a method and pass an argument (the UIImage) from the first view controller to the second like this.
FirstViewContoller.m
-(void) passImageToSecondVC (UIImage *) img
{
[<instanceOf_SecondViewController> receiveImg: img];
}
SecondViewContoller.m
-(void) receiveImage (UIImage *) img
{
//Code to display the image received
}
What Im asking is how can I find the name of the instance of the SecondViewController (shown by <> in the example code) generated by Xcode so I can call this method.
Although I'm very close to just doing this programmatically which I find much easier I wanna learn how to do this through the storyboard also I'm very open to hear other solutions to this problem. Thank you!
There's no way to do this through the storyboard. You don't access the view controller by its name. Each view controller has access to the tab bar controller through self.tabBarController. You can access individual controllers from the tab bar controller's viewControllers array. So, to get a reference to the controller in the second tab, you would use self.tabBarController.viewControllers[1].
Use delegates pattern.
Make one vc be a delegate of the other vc and communicate data between them. I think It's a common scenario.
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html
One of the things I don't like about WYSIWYG/visual programming, is when you get to a point where you need to step outside of the box, you're left scratching your head. I'm at such a point right now along my iOS learning curve.
I have a custom UICollectionView thing. In two places (create and edit points), I need to present a list to the user to enable/disable (select/deselect) items from a list. So I go to the storyboard and whip up something like this:
In the past, following tutorials, I would control-drag a link from some control to the NavigationController show in the middle, I would tell it was a modal segue, tune a couple of methods, and get an arrow connecting the two for my efforts.
But in this case, I don't have obvious points to start that action from. I do have a + button. But it needs to do some other things first, and if all is well, then programmatically initiate the open, and somehow get notified of the state when it returns. Same for the individual cells, they might want to configure my table controller, and then open it, and be notified when it closes.
So I'm looking for a recipe of how one does this, what the key methods I should be looking for are. Apple's docs are great for reference, but I find figuring out how to do something from scratch difficult.
After creating a segue in your storyboard, you can initiate a segue any time programmatically by calling
[self performSegueWithIdentifier:#"segueID" sender:person];
Where "segueID" is a string you set for your segue in interface builder in the Identifier field in the identity inspector (right menu panel, 4th tab).
The segue does not need to be created from a control, you can just create one directly from one view controller to another. I usually do this on the right side menu by right-clicking on one view controller object and dragging to another one. This way, it acts as a segue that you can initiate programmatically any time you want.
As for getting notified when you come back to a view controller, (unless I'm misunderstanding your question) you can use either:
(void)viewWillAppear:(BOOL)animated
(void)viewDidAppear:(BOOL)animated
Create a UINavigationController programmatically with a desired view controller set as a root view controller. Here is an example of what you could put in a method invoked when user taps the plus button:
UIViewController *vc = [[UIStoryboard storyboardWithName:#"YourStoryboardName" bundle:nil] instantiateViewControllerWithIdentifier:#"YourViewControllerID"];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:nc
animated:YES completion:nil];
To get a state, or information about the selected items you can use Delegation and declare a protocol. Example:
#protocol YourSampleDelegate <NSObject>
- (void)didSelectItem:(NSObject *)item;
#end
Then, your view controller (the one with the plus sign) should implement this protocol:
#interface ViewController : UIViewController<YourSampleDelegate>
...
#end
#implementation ViewController
...
#pragma mark - YourSampleDelegate conformance
- (void)didSelectItem:(NSObject *)item;
{
// Do something with the item.
}
#end
You also have to create a delegate property in a view controller with collection view and set the view controller with a plus as a delegate. There are tons of examples on the Internet. I hope this shows you the right direction.
my school group is creating an application in Xcode for iPhone 7.0 sdk. we already have the Tile map created, loaded, running. NPCs are loaded and appear on screen. we already have movement around the map. i have figured out how to create a CGRect around both the player and one NPC, but need ideas/ways to load a storyboard containing dialog. here is what we have:
CGRect sherpaRect;
sherpaRect.origin = CGPointMake(397,1908);
sherpaRect.size.width = 20;
sherpaRect.size.height = 20;
CGRect playerRect;
playerRect.origin = playerPos;
playerRect.size.width = 20;
playerRect.size.height = 20;
if (CGRectIntersectsRect(sherpaRect, playerRect)) {
//code needed to load storyboard
//added after question was initially asked
UIStoryboard *MainStoryboard=[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
EditorViewController *editorVC=[MainStoryboard instantiateViewControllerWithIdentifier:#"myEditor"];
[self presentViewController:editorVC animated:YES completion:nil];
//end added section
}
the collision works as putting a breakpoint at the commented out section (//code needed to load storyboard) successfully stops the program.
we are simply looking for how to load a storyboard at this point(and if any return actions might be needed upon exiting the storyboard and going back to the game map)
***new code causes an issue: "instance method presentViewController:animated:completion not found(return type default to 'id')"
What do you mean "load a storyboard?" A storyboard is a collection of "scenes", which represent the views and controls for a view controller.
Most iOS apps only use 1 storyboard, which can contain dozens of view controllers. If you've used XIB files, a storyboard is like a collection of XIB files.
You don't load a storyboard in response to a user action. Instead, you instantiate a view controller from an already-active storyboard.
Take a look at the UIStoryboard method instantiateViewControllerWithIdentifier:. You pass it a string identifier and it creates a view controller labeled with that id and gives it back to you. You can then present that view controller modally, push it onto a navigation controller stack, or a variety of other things.
What is it you are trying to accomplish in user-interface terms? Are you trying to display a new screen of some kind?
It's probably better to explain what you are trying to do with the user interface and then we can give you advice as to how to accomplish it.
I am trying to present a UIViewController inside a UIPopoverController. I've designed a view controller in Interface Builder, gave it a custom class (let's say MyAppTestViewController) and I'm trying to create a popover this way:
MyAppTestViewController *fxViewController = [MyAppTestViewController new];
self.fxPopover = [[UIPopoverController alloc] initWithContentViewController:fxViewController];
self.fxPopover.popoverContentSize = CGSizeMake(1024, 120);
[self.fxPopover presentPopoverFromBarButtonItem:_fxButton permittedArrowDirections:UIPopoverArrowDirectionDown animated:NO];
When I press the button, a popover is displayed at the correct place with the correct size, but it is empty. I've verified that the MyAppTestViewController's viewDidAppear method is being called (by NSLog), but the Popover's inside is empty:
Am I missing something?
I see that you mentioned in a comment that you're using a storyboard. So why not use a popover segue to your MyAppTestViewController? You could wire the segue directly to the Effects button on your toolbar. (Or, alternatively, call performSegueWithIdentifier: from your presenting view controller.) You might do a quick test by just throwing a UILabel into MyAppTestViewController right on the storyboard and seeing if it displays properly.
I think the problem is here:
MyAppTestViewController *fxViewController = [MyAppTestViewController new];
Generally you would use [[MyViewControllerClass alloc] initWithNibName:nil bundle:nil] (assuming you have a xib file with a matching name). I don't believe I have ever seen a view controller initialized with new. Everything in Objective-C is alloc-init.
Apple Docs: UIViewController Class Reference
Quote:
To initialize your view controller object using a nib, you use the
initWithNibName:bundle: method to specify the nib file used by the
view controller. Then, when the view controller needs to load its
views, it automatically creates and configures the views using the
information stored in the nib file.
EDIT:
Fascinating, well okay. It looks like you are right about the use of the new keyword, here is bit of an explanation of this.
So fine, that's not the problem. Have you tried breaking on the viewDidAppear method and using the debugger to print out the view properties, check its frame, check its superview, and so on, try to understand the problem better? You may already know how to do this, but the commands would be po self.view and so on.
In any case, I also found this, although it only goes into the mechanics of popover presentation and not content view assignment, which you seem to have down.
Okay, so far I've two view controllers in my storyboard. One with "login" elements and other as "User's home" sort of thing. I am intending to do the following : When user clicks on login, there's a bit of processing and then it should show to user's home screen..
When I do it via storyboard, i mean = control drag "login" button to user's home view it works fine. But I cant use that as I've to process the login data. It also shows some animation meanwhile. So, I've to do this shift programmatically. I wrote following code in the login button's IBAction ::
HomeViewController *homeView = [[HomeViewController alloc] init];
[self presentViewController:homeView animated:YES completion:NULL] ;
Now, this takes user to the intended view. However, the elements in the homeview (say a label, navigation bar are not being shown. And thats what my worry is.
(In theory, I can build entire view programatically but i think thats not the proper way of doing this, is it ? I want to make use of storyboard functionality in full i.e. design maximum UI in storyboard and use them from the backend how you want them to work.)
How do I do it ?
Cheers.
PS : I intend to add few more view controllers so at the moment i didn't think of navigation controller. not sure, if i should use it.
Using storyboards you should be using:
UIViewController *homeView = [self.storyboard instantiateViewControllerWithIdentifier:#"someID"];
[self presentViewController:homeView animated:YES completion:NULL] ;
Then set the ID to the view controller in storyboard like so:
Additionally, if you wish to there is absolutely nothing wrong with designing your UI entirely in code. Personally I prefer it. It gives you much more flexibility than interface builder.
In addition to NSPostWhenIdle's suggestion of instantiateViewControllerWithIdentifier, you can also define a segue between the two view controllers (not between the button and the second controller, but between the two view controllers):
Then give the segue a unique identifier, and then have your IBAction method do a performSegueWithIdentifier. This way your storyboard will continue to visually represent the various relationships between your view controllers.