I'm in the "awesome" position to have to support someone else's code even though before this project I have never worked in objective C or made iOS apps, so please excuse me if I'm doing something really obvious or stupid.
I needed a new view controller with a custom class. First I drew the view on my storyboard. Then I created a new class which I derived off of UIViewController. Then, I set the view's custom class to this new class I made. I hooked up the single button on the view to the code so I could make it close the view, then I made a (manual/modal) segue so I could call this new view from my main menu. All of this should be hooked up fine because I've used it before, but I'll show you how I call the segue anyway:
[self performSegueWithIdentifier:#"ScoreCard" sender:self];
Now, my problem is that when I press the button to run the above, I get the following error:
-[Scores _setViewDelegate:]: unrecognized selector sent to instance 0x9b4c460
Scores is the name of my custom UIViewController class. Its .h file looks pretty simple for now:
#import <UIKit/UIKit.h>
#interface Scores : UIViewController
- (IBAction)goBack:(id)sender;
#end
The .m file doesn't do anything besides what Xcode put in there by default and my implementation of goBack:
- (IBAction)goBack:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
Does anyone know what I'm forgetting? I successfully added another view controller yesterday in the same way and that one works just fine. Why doesn't this one?
The error that you're getting, -[Scores _setViewDelegate:]: unrecognized selector..., seems to be caused by setting the class of a UIView to a class that's not a subclass of UIView. Make sure that you've set the class for your view controller, not the view, to your custom class.
Related
I created a menu for my app, and I have three view attached to this menu, so when I added the final 3rd view controller and created the class to control that ViewController and when I run it It won't work it shows me this error: "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'", but then I take out the class form the view controller and it just work! I have created new Cocoa Touch class and added it again but it won't work! :( here is where I add the class to the ViewController
With the other classes I have, Like the RGBViewContoller it works but only when I create a new class won't work. I have tried to unlink and link again the segue in the storyboard but it doesn't work, then I tried to do this through code and also didn't work. Heroes the code:
if blueButton.selected {
self.navigationController?.pushViewController(CMYKViewController, animated: true)
}
So my mistake (this is so everyone know in what I mess up so you don't do it again as me) was that I created a UINavigationController subclass instead of a UIViewController subclass. Hope it helps to everyone who has this problem.
I saw many questions similar to mine but no solutions worked and this may be because I am creating and then importing an iOS framework into a project.
Basically, I have a SignIn framework and I want to show a webview if the user is not signed in.
My normal project will call my framework and if I need to authenticate, the SignIn framework will tell me to load a certain .xib to sign in.
In my framework, this .xib is named SignIn.xib It contains a view controller with a webview inside as you an see:
Now, in my framework, I init the view controller and call a function of the delegate to load the signInView:
NSString* const frameworkBundleID = #"iOSLoginSDK";
NSBundle* bundle = [NSBundle bundleWithIdentifier:frameworkBundleID];
SignInViewController* signInViewController = [[SignInViewController alloc] initWithNibName:#"SignIn" bundle:bundle];
[self.delegate loadSignInView:signInViewController];
In my project, I simply do the following and this method will be called by the delagate:
-(void) loadSignInView:(CYMSignInViewController *)signInViewController {
[self presentViewController:signInViewController animated:YES completion:nil];
}
However, I have the following error when I try to run the application:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SignIn" nib but the view outlet was not set.
I am using XCode 6.3.2
Edit 1: I think the problem happens because I have a view controller inside my xib. Can I do that?
Edit 2: Here are my outlets in my .xib
Edit3: I tried to recreate the nib but I still get the same error.
Here are the steps I did:
I created an empty xib
I added a view controller and then I added my element onto it
I created a view controller file and I set it as the custom class of the view controller
Am I missing something here?
Okay, so basically, it seems like you can't have a view controller in a standalone .xib. I think because the .xib is a view controller in a way (someone could clarify).
What I did, is that I created a view, set my design properly and then, I assigned my ViewController class file to the File's owner. That way, it is now working.
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
Hey guys I'm trying to get my app to load a new view when a certain method is called. Inside the method I have the code:
ViewController *GameOverViewController = [[ViewController alloc] init];
[self presentViewController:GameOverViewController animated:YES completion:nil];
which is taken straight from How to switch views programmatically in a ViewController? (XCode iPhone).
Anyways, when I try to switch from my view controller called Game to a view controller called GameOverViewController I just get a ton of errors. Mainly
"Unknown receiver 'ViewController'; did you mean 'UIViewController'
And my app crashes. I'm obviously doing something wrong but I have no idea what that is exactly. Do I have to declare the GameOverViewController in my Game.h or in my appDelegate or something?
EDIT: Both view controllers are in the same main.Storyboard file if that matters
The unknown receiver message means that it can't find the class definition for the view controller class called ViewController. Is that really the name of the class you're using for your "game over" view controller? And if so, have you done the #import "ViewController.h" at the start of this .m file?
The fundamental problem is that it cannot find the class called ViewController.
Setting that aside, we don't generally instantiate new view controllers using alloc and init anymore, as that answer may have implied. That was a technique used with NIBs (and only worked if the NIB name matched the class name).
For new developers, I might encourage you to start with storyboards. Any modern tutorial should walk you through how to use storyboards. (Google "iOS storyboard tutorial" and you'll probably get lots of hits.)
If, for example, your storyboard has a scene with a "storyboard identifier" of GameOverViewController, then you might programmatically instantiate it and present it with something like:
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"GameOverViewController"];
[self presentViewController:controller animated:YES completion:nil];
Or, if your storyboard had a segue from the current scene to the next scene, you'd make sure that segue had its own storyboard identifier, e.g. GameOverSegue, and then you'd perform it like so:
[self performSegueWithIdentifier:#"GameOverSegue" sender:self];
But find yourself a good introduction/tutorial on storyboards, as stumbling through Stack Overflow for answers will not be a very fruitful exercise.
For historical purposes, it's worth noting that if you were using NIBs, you can use the construct you referenced to in your question (but you'd have to make sure that (a) the class name was right; and (b) you did the #import that class header). And if the destination NIB had a different name than the class, you'd have to do something like:
UIViewController *controller = [[NSBundle mainBundle] loadNibNamed:#"nibname" owner:self options:nil]`;
[self presentViewController:controller animated:YES completion:nil];
But this is all academic unless you're using NIBs. If using storyboards, use one of the above patterns if you need to transition to a new scene programmatically.
You are in over your head. You should slow down and do some more studying or things are going to crash all over the place. I suggest going through a good book on iOS development and doing the exercises.
On to your question:
In the code you posted you're using a class "ViewController". There is no system-defined class "ViewController", although it is a common class name in example projects, and I think some of the project templates in Xcode even create a root view controller with that class name.
The name you give to your variable ("GameOverViewController" in the code above) is local and not really important. That's just a variable name. You can rename it lateForDinner if you want to, and it won't make any difference as long as you change that name everywhere in the scope in which it's defined.
The fact that you're being told that the class "ViewController" is unknown suggests that it hasn't been defined anywhere in your program.
You need an #interface and #implementation section that defines the ViewController class. Usually those will be in files called ViewController.h and ViewController.m, respectively. They might look something like this:
//ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController: UIViewController //Defines it as a subclass of UIViewController
// properties and methods of ViewController defined here
#end
And the .m file:
//ViewController.m
#implementation ViewController
// Implementation of ViewController methods go here.
#end
It's also possible to include the interfaces of multiple classes in a single header file, and the implementations of multiple classes in a single .m file, although I dislike this practice intensely. Keep it simple - one class per .h/.m file pair, with the file names identical to the class name.
I may go mad very soon.
This is the reason:
- I started up with Single View Application project with storyboards. Then I set the view controller class name in the storyboard for my viewController.
- Next step I created one pointer for this viewController in AppDelegate method ...didFinishLaunchingWithOpt... and filled it up by calling [myStoryboards instantiate...]. It works pretty good because I can call method like [vc1 setMyName] which does smthng like self.myName = #"Johnny";
- But here it comes. When I create IBAction method joined with button, this method doesn't know anything about "Johhny". And this is because I'm in another instance. When I check the address of "self" it is another one...
WhyWhyWhy??? Please help, how can I use still the same object - the one instantiated in AppDelegate by storyboards and the one from storyboards in "interface builder".
Thank you.
Oh my. I think I really underestamated it...
When we were talking about getting pointer of other viewControllers from storyboard...
I have initialViewController got by calling rootViewContr... And another one connected with segue (modal) where is UITableView. A get data on rootViewController and I want to show them on the other one in the list (UITableView). So I call segue (performSegueWithIdentifier), the other controller is shown but the list is clear. Because the method I call is working with tableView variable which is null :/ Because, again, I'm in another object. That is because I call that method storyboard instantiate... How can I get exactly the same viewController which I'm working in storyboard with. It is quite confusing for me :/
I read something about prepareForSegue and getting the pointer by destinationViewController but that is not what exactly I want. I need the pointer before I call segue method and the viewController is shown...
Thank you.
If you've set up your initial view controller properly in the storyboard, you don't need to assign it to the windows rootViewController property in -applicationDidFinishLaunchingWithOptions: as this is done for you automatically. It sounds like you're creating a second instance. To access the original instance setup by the storyboard simply do this in -applicationDidFinishLaunchingWithOptions:
InitialViewController *viewController = (InitialViewController *)self.window.rootViewController;
viewController.myName = #"Johnny";