I have a frustrating problem. I can't wrap my head around the "delegate thing".
My problem is that i can't set a Viewcontroller as the delegate.
-(IBAction)adminRegisterVC:(id)sender{
AdminSignUpViewController *adminSignUpVC = [[AdminSignUpViewController alloc] init];
[adminSignUpVC setDelegate:self]; // Gets an error message. See what error below.
[self.navigationController pushViewController:adminSignUpVC animated:YES];
}
it doesnt work with: adminSignUpVC.delegate = self; either.
error:
No visible #interface for 'AdminSignUpViewcontroller' declares the selector 'setDelegate:'
Is there something i should add to this:
#interface AdminSignUpViewController : UIViewController
I really need some help here!
Related
I am getting:
No visible #interface for 'BMPhotosViewController' declares the selector 'initWithPhoto:'
CODE:
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
BMPhotosViewController * photosVC = [[BMPhotosViewController alloc] initWithPhoto:#[[BMPhotoFullImage PhotoImageWithImage:image]]];
[self.presentationViewController presentViewController:photosVC animated:YES completion:nil];
});
}
Any suggestions?
if BMPhotosViewController is from a pod file, please check if the init method is publicly available in its header file, otherwise if its your own ViewController, simply declare the custom init method in the header's interface.
-(instancetype) initWithPhoto:(NSArray *)photos;
I am using a Category to add functionality to my ViewControllers. When the function from the category is run I get an error unrecognized selector sent to instance 0x7970ebf0. To test out the function I'm calling, I originally had the code within my viewDidLoad where I am calling the added function and it worked fine, so I don't think it is a problem with the function itself. So here is my code for the category and where I call it. Am implementing the Category incorrectly?
Here is "UIViewController+StatusBar.h"
#import <Foundation/Foundation.h>
#interface UIViewController (StatusBar)
-(void) addStatusBarBackground;
#end
Here is "UIViewController+StatusBar.m"
#import "UIViewController+StatusBar.h"
#implementation UIViewController (StatusBar)
-(void) addStatusBarBackground(){
//for making the background of the UIStatus bar black
UIView *statusBarView = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [[self view] bounds].size.width, 22)];
statusBarView.backgroundColor = [UIColor blackColor];
[self.navigationController.navigationBar addSubview:statusBarView];
}
#end
And then I call the function in viewDidLoad of my controller after including UIViewController+StatusBar.h like so
[self addStatusBarBackground]; This is where the error happens, when this is called.
Thanks for the help in advance!
I figured out what I was doing wrong. It ended out to be nothing to do with the category. The category was implemented correctly except for the declaration -(void) addStatusBarBackground(). The parenthesis needed to be deleted. The problem was that I did not select the target memberships that my app has on the right panel in my UIViewController+StatusBar.m file. So the file was not being compiled for my project. I guess its kind of like it wasn't included. I haven't dealt with target memberships before so that was why I was unaware of the problem. Thanks for the comments helping me figure out the answer!
I am new to using this method so I could be doing this completely wrong so here is my code:
#property (nonatomic, weak) ConverterViewController *converterViewController;
#property (nonatomic, weak) CalculatorViewController *calculatorViewController;
If I am understanding this code correctly, these are acting as references to Two different ViewControllers.
Then I have this in my viewDidAppear method:
[self addChildViewController:_converterViewController];
[_converterViewController didMoveToParentViewController:self];
[self.view addSubview:_converterViewController.view];
I am getting an NSException at the first line when I try and add it as a child view controller. So not knowing whether or not this should then call some methods in my ConverterViewController class I put some breakpoints within that class both the initWithNibName and viewDidLoad methods and I found that neither of these methods are being called, so Im not exactly sure what is wrong. Then again Im not really sure what could go wrong so any help is greatly appreciated.
This is all I get from the console:
libc++abi.dylib: terminating with uncaught exception of type NSException
Updated Answer:
[self addChildViewController:_converterViewController]; does not create the converterViewController.
It simply takes the converterViewController object and adds it as a childViewController to self.
You will need to allocate memory and instantiate the object converterViewController before -addChildViewController: or else it's value will be nil and nothing will happen.
So... something this:
_converterViewController = [[ConverterViewController alloc] initWithNibName:#"ConverterViewController"
bundle:nil];
//now... adding it as childViewController should work
[self addChildViewController:_converterViewController];
[_converterViewController didMoveToParentViewController:self];
//optional: give it a frame explicitly so you may arrange more childViewControllers
//[_converterViewController.view setFrame:CGRectMake(0,0,100,100)];
[self.view addSubview:_converterViewController.view];
i added a custom protocol to one of my classes and i am getting a compiler warning when i attempt to set the delegate during a prepareForSegue: method. the warning i get is...
Sending 'MyCustomViewControllerClass *const __strong' to parameter of incompatible type 'id<NSFileManagerDelegate>'
the project builds and runs and everything works fine minus the warning. if i add <NSFileManagerDelegate> to my custom class the warning goes away. am i missing something or is this a bug in Xcode (6 beta)? the code is standard code for setting up a protocol / delegate but i will post it anyways...
SomeSecondClass.h
#import <UIKit/UIKit>
#class SomeSecondCustomViewController;
#protocol SomeSecondCustomViewControllerDelegate <NSObject>
- (void)doThisForMe
#end
#interface SomeSecondCustomViewController : UIViewController
#property (weak, nonatomic) id <SomeSecondCustomViewControllerDelegate> delegate;
#end
SomeSecondClass.m
#interface SomeSecondViewController ()
…stuff
-(void)someMethod {
[self.delegate doThisForMe];
}
#end
CustomClass.h
#import <UIKit/UIKit.h>
#import “ SomeSecondViewController.h”
#interface MyCustomViewController : UIViewController <SomeSecondCustomViewControllerDelegate>
//adding on <NSFileManagerDelegate> removes the warning...
#end
CustomClass.h
...standard stuff...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
//this is where the warning happens on "self"
[segue.destinationViewController setDelegate:self];
}
}
- (void)doThisForMe {
//doing some stuff...
}
#end
i have opened previous projects where the warning did not exist and now the same warning appears. i am wondering if this is an Xcode problem?
You are running into an issue caused by an ambiguity in how Objective-C finds a matching selector and dealing with an id reference.
UIStoryboardSegue destinationViewController returns an id. Your code then tries to call the setDelegate method on this id reference. Since there is no information about what this id actually references, it doesn't know which setDelegate: method you might mean (there are many). So the compiler scans through the list it knows of and picks one. In this case it chose the setDelegate: method from the NSFileManager class. Since self doesn't conform to the NSFileManagerDelegate protocol, you get the warning.
You could ignore the warning and your code will work fine in this case.
The better solution is to help the compiler by adding a cast:
[(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self];
This will let the compiler know which setDelegate: method you really mean.
BTW - Adding NSFileManagerDelegate to your class is not a valid solution even if it works at the moment. A simple reordering of some import statements could lead the compiler to make a different choice and your warning would return but complain about not conforming to some other protocol.
as it turns out, this is a bug / change in Xcode 6 beta. running this exact same code on Xcode 5.1.1 produces no warnings or errors. the problem is cause because in Xcode 6 the compiler is asking for type
(id<NSFileManager>)
for the delegate. in Xcode 5.1 the compiler is simply expecting
(id)
for the delegate type.
as rmaddy stated, by casting the type in
[(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self];
it did remove the warning, but this should be an unnecessary step and will chalk it up to a problem with Xcode.
Try explicitly typing (giving type to) the destinationVC, like this:
SomeSecondCustomViewController *vc = (SomeSecondCustomViewController *)segue.destinationViewController;
vc.delegate = self;
#rmaddy provides the correct answer. This is a more detailed example for those of us who are lightly schooled in the ways of Objective-C.
I changed my code from:
[[segue destinationViewController] setDelegate:self];
UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController];
self.flipsidePopoverController = popoverController;
popoverController.delegate = self;
to:
[(UIPopoverController *)segue.destinationViewController setDelegate:self];
UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController];
self.flipsidePopoverController = popoverController;
popoverController.delegate = self;
and the warnings disappeared.
I think setting the delegate for the KalViewController correctly - copying both the Holiday & NativeCal demo - but I must not be because I'm getting the following error when I click upon a date cell:
-[UINavigationButton didSelectDate:]: unrecognized selector sent to instance
When I set breakpoints on All Exceptions I see that it's raising an exception in KalGridView.m in this function:
- (void)setSelectedTile:(KalTileView *)tile
{
if (selectedTile != tile) {
selectedTile.selected = NO;
selectedTile = [tile retain];
tile.selected = YES;
[delegate didSelectDate:tile.date]; // exception raised here
}
}
And here's the code where I set the delegate (pretty much copied from the demo code):
- (void) viewDidLoad
{
KalViewController *calendar = [[KalViewController alloc] init];
calendar.delegate = self;
[[self.view viewWithTag:1] addSubview:calendar.view];
....}
The error makes sense because I'm setting the delegate to my own ViewController which doesn't implement didSelectDate. On the other hand, neither does the Holiday and NativeCal classes which are set at the KalViewController's delegate, both of which are of type
NSObject <UIApplicationDelegate, UITableViewDelegate>
Thanks a pile.. I'm more than a touch stuck.
This is one of those rare instances where the delegate should probably be retained because it's being released and replaced. Override -setDelegate: and retain your delegate.