Why is contactDelegate not being set? - ios

I'm getting the following warning from the line
self.physicsWorld.contactDelegate = self;
Assigning to 'id' from incompatible type 'PlayLevel *__strong'
-(id)initWithSize:(CGSize)size level:(int)level{
if (self = [super initWithSize:size]) {
_level = level;
self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;
Not at all sure what's causing it.
This is what my header looks like:
#import <SpriteKit/SpriteKit.h>
#interface PlayLevel : SKScene
-(id)initWithSize:(CGSize)size level:(int)level;
#end
Any idea's what's causing it? I kind of need a contactDelegate. Thanks!

You should declarer on your class interface (inside <>) that your class implement the delegate.

you will have to add the delegate reference in your header file. For example if we are using the UINavigationController delegates we add <UINavigationControllerDelegate> in the header file. Similary you will have to add the contact delegate

In your header where you declare that PlayLevel extends SKScene, you need to also declare that it implements the SKContactDelegate interface like so:
#interface PlayLevel : SKScene <SKPhysicsContactDelegate>

Related

Presenting a SKSpritenode from different class ("addChild")

I have a Class for my Sprite and I'm trying to addChild from that class. The problem is it renders it and doesn't crash - I just can't see the image. I know the images position is right because created and added the child from the gameScene class and it worked and loaded.
I'm thinking this isn't working because its not subclass of SKscene that's why I added the main node from gameScene but didn't solve the problem.
I set up a "mainNode" node
keys is just the name of the sprite and its the class name
I know the image is being rendered its just not visible for some reason.
I know this because if I add no image name not "key_green" and change it to nothing. I get an console msg saying it can't find that image.
gameScene.m
#import "GameScene.h"
#import "Keys.h"
#implementation GameScene
#synthesize mainNode;
-(void)didMoveToView:(SKView *)view {
self.backgroundColor = [UIColor whiteColor];
mainNode = [SKNode node];
[self addChild:mainNode];
Keys * KeysOBJ =[[Keys alloc] init];
[KeysOBJ initKeys];
}
keys.h
#import <SpriteKit/SpriteKit.h>
#import "GameScene.h"
#interface Keys : SKSpriteNode{
SKSpriteNode * key1;
}
#property SKNode* mainNode;
-(void)initKeys;
-(void)loadKeys;
keys.m
#import "Keys.h"
#import "GameScene.h"
#implementation Keys{
}
#synthesize mainNode;
-(void)initKeys{
key1 = [SKSpriteNode spriteNodeWithImageNamed:#"key_red"];
key1.position = CGPointMake((self.frame.size.width)- (self.frame.size.width)+350, (self.frame.size.height)-(self.frame.size.height)+50);
[mainNode addChild:key1];
}
Your mainNode is nil in your Keys because you never set it before you call initKeys. This in theory will get it working.
Keys * KeysOBJ =[[Keys alloc] init];
KeysOBJ.mainNode = mainNode;
[KeysOBJ initKeys];
Also consider this
key1.position = CGPointMake((self.frame.size.width)- (self.frame.size.width)+350, (self.frame.size.height)-(self.frame.size.height)+50);
self doesn't have a size because you just called init and never supplied a texture or a size. Meaning your sprite location will likely be 350,50.
With that being said you are over complicating it. Your Keys shouldn't be a subclass of SKSpriteNode if you are never going to set a texture to it. It should be a SKNode.
Hopefully that makes some sense and gets you pointed back in the right direction.

How can I create and define a SKSpriteNode in a different class and access it? Xcode 6 :)

I was wondering how I could create a SKSpriteNode in a class and use it and add it in another class. I tried using #property, but I probably used it wrong. Could someone please help? :0
Thanks!!
EDIT:
I pretty much just created a property like this:
#property (nonatomic, strong) SKSpriteNode *testNode;
and in the other class which is GameScene I imported the class with the property and tried to type in testNode to try and change it's properties but nothing popped up. I even tried 'testClass.testNode' or 'self.testNode'.
testClass.h ---
#interface testClass : SKScene
#property (nonatomic, strong) SKSpriteNode *testNode;
#end
GameScene.m ---
-(void)didMoveToView:(SKView )view {
/ Setup your scene here */
testNode = [SKSpriteNode spriteNodeWithImageNamed:#"Character"];
}
GameScene.h ---
#import <SpriteKit/SpriteKit.h>
#import "testClass.h"
#interface GameScene : SKScene{
}
You could create a new class which inherits from SKSpriteNode and instantiate it in your scene:
import SpriteKit
class MyNode: SKSpriteNode {
override init() {
}
}
And later:
let myNode = MyNode()
Here's the Swift guide about inheritance:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-ID193
In GameScene, first initialize the other class:
testClass *testClassInstance = [[testClass alloc] initWithSize:self.size]];
Then, get the property:
testClassInstance.testNode

Accessing variables from another class when importing a .ccbi file

I know this topic is covered in a hundred posts here, but I'm having a lot of trouble with this particular instance and cannot figure it out.
Basically, I'm using Spritebuilder to import sprites/nodes into my game. I import a sprite of some specific class in the body of the GameScene class, but I want to be able to define a variable inside of my sprite class, and then edit it from the GameScene class. For example, if my sprite collects a coin inside the GameScene, I want to change the speed of my sprite inside of the update method in the sprite class.
Below is my code, but unfortunately it isn't working. The variable increaseY and increaseX do not appear to be available in my GameScene class. I know this is because I didn't instantiate the Penguin class properly, but I don't know how to properly create an instance of this class while simultaneously importing the .ccbi file of it. The problem line is commented on and has a bunch of ** next to it to easily find it. It's in GameScene.m. I really appreciate the help, been stuck on this for several hours.
Penguin.h
#import "CCSprite.h"
#interface Penguin : CCSprite
{
float xPosition;
float yPosition;
}
#property (nonatomic,assign) float increaseY;
#property (nonatomic,assign) float increaseX;
#end
Penguin.m
#import "Penguin.h"
#implementation Penguin
#synthesize increaseX;
#synthesize increaseY;
- (id)init {
self = [super init];
if (self) {
CCLOG(#"Penguin created");
}
return self;
}
-(void) update:(CCTime)delta
{
self.position = ccp(self.position.x + increaseX,self.position.y + increaseY);
}
#end
GameScene.h
#import "CCNode.h"
#interface GameScene : CCNode
#end
GameScene.m
#import "GameScene.h"
#import "Penguin.h"
#implementation GameScene
{
CCPhysicsNode *_physicsNode;
CCNode *_catapultArm;
CCNode *_levelNode;
CCNode *_contentNode;
}
// is called when CCB file has completed loading
- (void)didLoadFromCCB {
self.userInteractionEnabled = TRUE;
CCScene *level = [CCBReader loadAsScene:#"Levels/Level1"];
[_levelNode addChild:level];
}
// called on every touch in this scene
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
[self launchPenguin];
}
- (void)launchPenguin {
// loads the Penguin.ccb we have set up in Spritebuilder
CCNode* penguin = [CCBReader load:#"Penguin"];
penguin.position = ccpAdd(_catapultArm.position, ccp(16, 50));
[_physicsNode addChild:penguin];
//THE FOLLOWING LINE DOES NOT WORK********************************
penguin.increaseY = 1;
// Gives Error------Property "increaseX" not found on object of type "CCNode *"
self.position = ccp(0, 0);
CCActionFollow *follow = [CCActionFollow actionWithTarget:penguin worldBoundary:self.boundingBox];
[_contentNode runAction:follow];
}
You have to change this line:
CCNode* penguin = [CCBReader load:#"Penguin"];
To this line:
Penguin* penguin = (Penguin*)[CCBReader load:#"Penguin"];
In the old line you were using the compiler was giving you an error because the CCNode class does not have a property called increaseX. increaseX is part of the Penguin class. If you want to access properties of the Penguin class you need to use a cast and let the compiler know, that what you are loading using the CCBReader is actually a Penguin instance.

iOS error: No visible #interface for 'xxxx' declares the selector 'alloc'

Here is my TextValidator class:
//TextValidator.h
#import <Foundation/Foundation.h>
#interface TextValidator : NSObject
- (BOOL) isValidPassword:(NSString *)checkPassword;
- (BOOL) isValidEmail:(NSString *)checkString;
- (BOOL) isEmpty:(NSString *)checkString;
#end
// TextValidator.m
#import "TextValidator.h"
#implementation TextValidator
- (BOOL) isEmpty:(NSString *)checkString
{
return YES;
}
- (BOOL) isValidPassword:(NSString *)checkPassword
{
return YES;
}
- (BOOL) isValidEmail:(NSString *)checkString
{
return YES;
}
#end
This is the way I try to initialise the TextValidator class in ViewController.m:
//ViewController.h
#import <Foundation/Foundation.h>
#interface SignUpViewController : UIViewController <UITextFieldDelegate>
#end
//ViewController.m
#import "SignUpViewController.h"
#import "TextValidator.h"
#interface SignUpViewController ()
#property TextValidator *myValidator;
#end
#implementation SignUpViewController
- (void)viewDidLoad
{
[[self.myValidator alloc] init]; //iOS error: No visible #interface for 'TextValidator' declares the selector 'alloc'*
[super viewDidLoad];
}
#end
When I try to compile the code I get the following error:
No visible #interface for 'TextValidator' declares the selector 'alloc'.
TextValidator class inherits from NSObject and as far as I know init and alloc functions are already defined at the base class. So why does the program gives such an error?
Note that, I already checked this topic and it doesn't work for me.
My psychic debugger, without reading your code, tells me you're calling alloc on an object instance, rather than a class. The alloc method is a static method defined by classes (typically inherited from NSObject) that returns a new instance of the underlying object. You can't ask an instance to allocate itself!
Now looking at the code, I see that you want:
self.myValidator = [[TextValidator alloc] init];
to construct a new instance, and assign it to the myValidator property.
Replace
[[self.myValidator alloc] init];
with
self.myValidator = [[TextValidator alloc] init];
The error signals that you have not implemented the alloc instance method for self.myValidator, which is true. But that's a class method that applies for all NSObject objects.
Your syntax of creating object is incorrect. Correct code:
self.myValidator = [[TextValidator alloc] init];
If you experience this randomly (like when you are changing branches), not because you forgot to declare selector.
Go to file inspector > Target Membership
uncheck the targets
then check it again
This will refresh your project.pbxproj
Then if you build, you'll see your real problem
For Others :
Check the varible name is not like the class name.
Well it happend to me.
XXXViewController * XXXViewController = [[XXXViewController alloc] init];
Don't tell anyone like I did right now.
For those who get the error of "no visible #interface for declares the selector ..."
such an error usually happens when you have mistyped the name of the method, or that method doesn't belong to that class at all and doesn't exist in your class
I had this problem today and solved it on my own. Basically you could also not be satisfying all the requirements of the function / procedure.
Go into the class itself and make sure your declaring all the requirements.
I took the class out of the header library and compared it word for word to verify it matches the function using it.

No known class method for selector 'setRegion:animated:'

I tried some stuff in xcode, and i'm using this code for my MapView.
No known class method for selector 'setRegion:animated:'
I have made three View Controller with with 3 .h and .m files.
What's my mistake?
.m
#import "myPlacesAllTime.h"
#import <MapKit/MapKit.h>
#interface myPlacesAllTime ()
#end
#implementation myPlacesAllTime
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
MKCoordinateRegion startRegion = { {0.0,0.0}, {0.0,0.0} };
startRegion.center.latitude = 35.88905;
startRegion.center .longitude = -17.605591;
startRegion.span.latitudeDelta = 0.1;
startRegion.span.longitudeDelta = 0.1;
[myPlacesAllTime setRegion:startRegion animated: NO];
}
.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface myPlacesAllTime : UIViewController <MKMapViewDelegate>{
__weak IBOutlet MKMapView *myPlacesAllTime;
}
#end
You have chosen the same name myPlacesAllTime for the class and for an
instance variable of that class.
To solve the problem, rename the class, e.g. to MyPlacesController or similar.
Note that the convention is to let
class names start with a capital letter.
I think you problem may be a naming issue. The class you've created is named the same as the instance of MKMapView you have. I would follow convention and name your class with caps, but to solve the current problem try using
[self.myPlacesAllTime setRegion:startRegion animated:NO];
to see if it has a different outcome. You'll have to make your instance a property of the class, as stated in the comments below, which I missed in my original answer.
If you are intending to use setRegion:animated: at class level then make sure you have defined a method like this:
+ (void)setRegion:(OBJ_Type)iType animated:(OBJ_Type)iAnimated {
And f you are intending to use setRegion:animated: at object level then make sure you have defined a method like this:
- (void)setRegion:(OBJ_Type)iType animated:(OBJ_Type)iAnimated {
and in this case you need to call this method like this:
[self setRegion:PARAM animated:PARAM];

Resources