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;
Related
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!
I'm trying to have another object call a selector. I'm attempting to define this selector from another class by defining the selector property. It doesn't seem to be working like I expect.
ComboBox.h
#property (nonatomic) SEL onComboSelect;
ComboBox.m
-(void)doneClicked:(id) sender
{
[textField resignFirstResponder]; //hides the pickerView
NSLog(#"DONE CLICKED CALLED");
[self performSelector:#selector(onComboSelect)];
}
OtherClass.h
#interface OtherClass : BaseViewController
{
ComboBox *combo;
}
-(void)comboSelector;
OtherClass.m
// in viewDidLoad
combo = [[ComboBox alloc] init];
combo.onComboSelect = #selector(comboSelector);
-(void)comboSelector
{
NSLog(#"COMBO SELECTOR");
}
I see "DONE CLICK CALLED" in the logs, but not "COMBO SELECTOR". So I know doneClicked is being called, but the selector doesn't seem to be working. What am I doing wrong? Is there a better way to do this?
A #selector is just a method name - it does not include any context about the class on which it is defined. So this [self performSelector:#selector(onComboSelect)] is just invoking the method on self. In addition to the selector, you also need a reference to the object on which you want to call it.
Notice how some built-in classes (like UIControl) take both a target object and action selector.
There are a 2 major issues in your code.
1.
onComboSelect is a SEL so no need to use the #selector again.
Instead of:
[self performSelector:#selector(onComboSelect)];
Use :
[self performSelector:onComboSelect];
2.
You are calling the selector on self from ComboBox class, so it'll call the selector on ComboBox object (if defined) not on OtherClass object
Your answers were helpful. Here is what I did:
added to ComboBox.h
#property (nonatomic, weak) UIViewController *parentViewController;
added to ComboBox.m
-(void)doneClicked:(id) sender
{
[textField resignFirstResponder]; //hides the pickerView
if ([parentViewController respondsToSelector:#selector(comboSelector)])
[parentViewController performSelector:#selector(comboSelector)];
}
added to OtherClass.m
combo.parentViewController = self;
#property (nonatomic) SEL onComboSelect <-- This property is not needed in ComboBox.h.
SEL is a point of objc_seletor,and in object_seletor runtime can find the
objc_method ,that define
objc_method {
SEL method_name OBJC2_UNAVAILABLE;
char *method_types OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE;
}
and IMP is the point of method,and you can find this in "runtime.h" file.
Any noe kow how to find objc_method by object_seletor ? and I cannot find the define of objc_seletor struct.
I created a singleton in ios7 like this:
SharedData.h
#interface SharedData : NSObject
{
}
+ (id)sharedInstance;
#property (strong, nonatomic) NSMutableArray *list;
#end
SharedData.m
#import "SharedData.h"
#implementation SharedData
#synthesize list;
// Get the shared instance thread safe
+ (SharedData *)sharedInstance {
static dispatch_once_t once = 0;
static SharedData *sharedInstance = nil;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (id)init {
self = [super init];
if (self) {
//initialize
list = [[NSMutableArray alloc] init];
}
return self;
}
#end
I always use this code to access this class:
SharedData *sharedData = [SharedData sharedInstance];
The problem is now when I switch the view in my viewDidLoad method the list is empty but in my viewDidAppear method everything is fine. Any ideas?
EDIT:
This is the code how I change the views:
SharedData *sharedData = [SharedData sharedInstance];
//clear feed and add new feed
[sharedData.list removeAllObjects];
[sharedData.list addObjectsFromArray:newList];
//show new gui
[self.navigationController performSegueWithIdentifier:#"goToMain" sender:self];
NOTE: I push from a normal ViewController to a TabBarController -> NavigationController -> TableViewController to display the list.
I guess you have the confusion between these two viewcontroller methods:
-(void)viewDidLoad{
//
}
&
-(void) viewDidAppear{
//
}
viewDidAppear is the method which is called each time your view changes but viewDidLoad is the method which is not necessarily called each time your view changes.
ViewDidLoad method is called when view loads for the first time, after that it doesn't get called until the views are removed/released.
P.S: I suggest you to put the breakpoint in your viewDidLoad and viewDidAppear method and feel it. Your answer lies there.
Hope this helps you alot.
Good Luck.
The problem was i created a segue which went from the button to the next view. Because of this the viewDidLoad gets earlier called than the list assigned. I just changed the segue to go from view to view.
How are you changing from one viewController to the other? Wich classes are the parents of your destination ViewController?,
If you are modifying properties of the view in the prepareForSegue method... you are forcing the view to load.
For example, you are setting the list of your singleton in prepareForSegue, but before setting the list you are modifying a property of your destination viewController. (doing something like destVC.view = XXX or destVC.viewControllers = XX if you are subclassing a UITabBarViewController...) Then you are triggering the viewDidLoad method , and it's executing before you have set the list to the correct value.
Or maybe you are seguing in two different places to the destinationViewController. And when the viewDidLoad happens, you still have not updated the list on the singleton.
Here is the transcription of the chat with the poster of the question: https://chat.stackoverflow.com/transcript/55218
Here's my class with my custom init method:
// Piece.h
#import <Foundation/Foundation.h>
#interface Piece : CCSprite
#property (nonatomic) int pieceNumber;
+(Piece *)initWithPieceImage:(UIImage*)piece pieceName:(int)pName;
#end
// Piece.m
#import "Piece.h"
#implementation Piece
#synthesize pieceNumber = _pieceNumber;
+(id)initWithPieceImage:(UIImage *)piece pieceName:(int)pName
{
return [[[self alloc] initWithPieceImage:piece pieceName:pName] autorelease];
}
-(Piece*)initWithPieceImage:(UIImage *)piece pieceName:(int)pName
{
CCSprite *bgImage = nil;
if ( (self=[super init]) )
{
bgImage = [CCSprite spriteWithCGImage:piece.CGImage
key: [NSString stringWithFormat:#"%i",pName]];
}
return (Piece*)bgImage;
}
#end
I instantiated the Piece class like this to add it to the layer:
Piece *newPiece = [Piece initWithPieceImage:myUIImage pieceName:1];
[newPiece setPieceNumber:2]; //Error in this line
[self addChild: newPiece z:1];
However I have tried it like this and it perfectly works:
Piece *newPiece = [[Piece alloc] init];
[newPiece setPieceNumber:2];
but this is not what I want.
and here is the error I get:
[CCSprite setPieceNumber:]: unrecognized selector sent to instance 0x85f1050
Terminating app due to uncaught exception NSInvalidArgumentException, reason: -[CCSprite setPieceNumber:]: unrecognized selector sent to instance 0x85f1050
Aparently it looks like the problem is how Im trying to init my object.
I'm a newcomer to objective-c so I cant figure out what is wrong here.
any idea of what am I doing wrong here?
How can I achieve this approach and access the properties of my instantiated object with custom init method?
You have a mess in your code. In -(Piece*)initWithPieceImage:(UIImage *)piece pieceName:(int)pName you return a CCSprite object instead of a Piece. You assign self with an object but return another, of an incorrect type.
init returns the correct type (because you haven't reimplemented it), so it works, but you haven't actually initialized the image correctly.
You need to change your method like so:
-(Piece*)initWithPieceImage:(UIImage *)piece pieceName:(int)pName
{
return [super initWithCGImage:piece.CGImage key:[NSString stringWithFormat:#"%i",pName]];
}
It is because in your init method, you are for some reason creating a CCSprite object and returning that instead of the Piece object. Because of that, it will not be an object of your Piece class and will not respond to any of Piece's methods.
Instead of creating a new CCSprite object to set those properties to, you want to set those on self or super.
My app is crashing when trying to access a method in my parentViewController. Here is the layout in StoryBoard
MainViewController = STLMMainViewController (ParentViewController)
Scene1 = STLMTimeDateViewController (ChildViewController)
Here is the code for STLMTimeDateViewController
#import "STLMTimeDateViewController.h"
#import "STLMMainViewController.h"
#interface STLMTimeDateViewController ()
#property (nonatomic, strong) STLMMainViewController *stlmMainViewController;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"The name of the controller %#",self.navigationController.parentViewController);
stlmMainViewController= (STLMMainViewController *) self.parentViewController;
[stlmMainViewController locationButtonSelected]; // This is where the App crashes
NSLog(#"TimeDateController");
}
The App Runs, but when STLMMainViewController is called, the app crashes with the following error:
2013-02-10 16:33:57.422 MyApp[9120:c07] The name of the controller <STLMMainViewController: 0x83850d0>
2013-02-10 16:33:57.434 MyApp[9120:c07] -[UINavigationController locationButtonSelected]: unrecognized selector sent to instance 0x8371a70
If I remove the following line:
stlmMainViewController = (STLMMainViewController *) self.parentViewController;
and just leave
[stlmMainViewController locationButtonSelected];
The App runs, no error, but the following method in [STLMMainViewController locationButtonSelected] does not get called (I never see the log):
-(void)locationButtonSelected
{
[LocationButton setSelected:YES];
[eatDrinkbutton setSelected:NO];
[timeCalButton setSelected:NO];
[carButton setSelected:NO];
[contactButton setSelected:NO];
NSLog(#"LocationButtonSelected Method");
}
All the properties in the locationButtonSelected method and the method itself is declared in .h of STLMMainViewController for public access.
Thanks
You might try this:
self.stlmMainViewController= (STLMMainViewController *)self.navigationController.parentViewController;
(EDIT: actually, as someone else just pointed out, you might want to use presentingViewController instead.)
It looks like you had it right in the log message right before this. You want your navigation controller's parent in this case.
BTW, the reason you don't crash when you delete this line, is because you end up sending the locationButtonSelected to nil. That won't crash, but it also won't do anything either.