我对编写Objective C代码有点新意,我确信我的风格很糟糕。我已经在这个问题上检查了几个其他解决方案,但我仍然感到困惑。据我所知,到目前为止,这似乎是一个内存管理问题。这是设置,我有2个类,一个名为MyScene.m(通用精灵套件场景)和一个名为Buttons.m的类,用于以编程方式设计按钮。这是一个OS X应用程序(不是IOS APP)。
来自MyScene.m:
-(id)initWithSize:(CGSize)size {
...
NSColor *col = [NSColor colorWithRed:90.0/255.0 green:90.0/255.0 blue:90.0/255.0 alpha:1.0];
NSColor *col2 = [NSColor colorWithRed:40.0/255.0 green:40.0/255.0 blue:40.0/255.0 alpha:1.0];
Button *button = [[Button alloc] initRoundRectNormal:col Selected:col2 Size:CGSizeMake(200, 100)];
button.position = CGPointMake(200, 400);
[button setText:@"HI"];
[button setTextSize:80];
[self addChild:button];
...
}
-(void)mouseDown:(NSEvent *)theEvent {
CGPoint location = [theEvent locationInNode:self];
SKSpriteNode *spriteTouched = (SKSpriteNode*)[self nodeAtPoint:location];
if ([spriteTouched.name isEqualToString:@"button"]) {
Button *button = (Button*)spriteTouched;
[button setIsPressed:YES];
}
}
这是整个Button.m类:
#import "Button.h"
@interface Button()
@property SKShapeNode *shape;
@property SKShapeNode *shapeShadow;
@property SKLabelNode *labelShadow;
@property ButtonType shapeType;
@property NSColor *normalColor;
@property NSColor *selectedColor;
@property CGSize size;
@end
@implementation Button
@synthesize label = _label;
@synthesize isPressed = _isPressed;
@synthesize shape = _shape;
@synthesize shapeShadow = _shapeShadow;
@synthesize labelShadow = _labelShadow;
@synthesize shapeType = _shapeType;
@synthesize normalColor = _normalColor;
@synthesize selectedColor = _selectedColor;
@synthesize size = _size;
-(id)initSquareNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor SideLength:(int)sideLength {
if(self = [super init]) {
//init colours and size
_normalColor = normalColor;
_selectedColor = selectedColor;
_size = CGSizeMake(sideLength, sideLength);
_shapeType = SQUARE;
[self initButton];
}
return self;
}
-(id)initRoundRectNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size {
if(self = [super init]) {
//init colours and size
_normalColor = normalColor;
_selectedColor = selectedColor;
_size = size;
_shapeType = ROUNDED_REC;
[self initButton];
}
return self;
}
-(id)initCircleNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size {
if(self = [super init]) {
//init colours and size
_normalColor = normalColor;
_selectedColor = selectedColor;
_size = size;
_shapeType = CIRCLE;
[self initButton];
}
return self;
}
-(void)initButton {
[self initShape];
[self initLabel];
[self initLabelShadow];
}
-(void)initLabel {
_label = [[SKLabelNode alloc] init];
_label.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
_label.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
_label.zPosition = 2;
[_shape addChild:_label];
}
-(void)initLabelShadow {
NSColor *black = [NSColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.4];
_labelShadow = [_label copy];
_labelShadow.fontColor = black;
_labelShadow.position = CGPointMake(_label.position.x, _label.position.y - 5);
_labelShadow.zPosition = _label.zPosition - 4;
_labelShadow.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
_labelShadow.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
[_label addChild:_labelShadow];
}
-(void)initShape {
switch (_shapeType) {
case ROUNDED_REC: {
_shape = [SKShapeNode node];
[_shape setPath:CGPathCreateWithRoundedRect(CGRectMake(-(_size.width/2), -(_size.height/2), _size.width, _size.height), 4, 4, nil)];
_shape.strokeColor = _shape.fillColor = _normalColor;
[self addChild:_shape];
break;
}
case CIRCLE: {
_shape = [SKShapeNode node];
[_shape setPath:CGPathCreateWithRoundedRect(CGRectMake(-(_size.width/2), -(_size.height/2), _size.width, _size.height), _size.width/2, _size.height/2, nil)];
_shape.strokeColor = _shape.fillColor = _normalColor;
[self addChild:_shape];
break;
}
case SQUARE: {
_shape = [SKShapeNode node];
[_shape setPath:CGPathCreateWithRoundedRect(CGRectMake(-(_size.width/2), -(_size.height/2), _size.width, _size.height), 0, 0, nil)];
_shape.strokeColor = _shape.fillColor = _normalColor;
[self addChild:_shape];
break;
}
default:
break;
}
_shape.name = @"button";
_shape.zPosition = -5;
_shape.lineWidth = 1;
[self initShadow];
}
-(void)initShadow {
float r = 0.0, g = 0.0, b = 0.0, a = 0.8;
NSColor *black = [NSColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a];
_shapeShadow = [_shape copy];
_shapeShadow.fillColor = black;
_shapeShadow.strokeColor = [NSColor colorWithRed:255.0*a/255.0 green:255.0*a/255.0 blue:255*a/255.0 alpha:0.8];
_shapeShadow.lineWidth = 1;
_shapeShadow.zPosition = _shape.zPosition - 1;
CGPoint shadowPosition = CGPointMake(_shape.position.x, _shape.position.y - 10);
_shapeShadow.position = shadowPosition;
[self addChild:_shapeShadow];
}
-(void)setText:(NSString*)text {
_label.text = text;
_labelShadow.text = text;
}
-(void)setTextSize:(int)size {
_label.fontSize = size;
_labelShadow.fontSize = size;
}
-(void)setIsPressed:(bool)isPressed {
if (isPressed)
_shape.fillColor = _shape.strokeColor = _selectedColor;
else
_shape.fillColor = _shape.strokeColor = _normalColor;
}
-(bool)isPressed {
return _isPressed;
}
@end
来自Button.h:
#import <SpriteKit/SpriteKit.h>
typedef enum ButtonType {
CIRCLE,
SQUARE,
ROUNDED_REC
} ButtonType;
@interface Button : SKSpriteNode
@property SKLabelNode* label;
@property bool isPressed;
-(id)initSquareNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor SideLength:(int)sideLength;
-(id)initRoundRectNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size;
-(id)initCircleNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size;
-(void)setText:(NSString*)text;
-(void)setTextSize:(int)size;
@end
万一你想知道我想要做什么,我试图在点击它时改变按钮的颜色。
这是错误:
2014-09-14 13:49:05.625 UI[1602:303] -[SKShapeNode setIsPressed:]: unrecognized selector sent to instance 0x61800011fd10
2014-09-14 13:49:05.626 UI[1602:303] -[SKShapeNode setIsPressed:]: unrecognized selector sent to instance 0x61800011fd10
2014-09-14 13:49:05.628 UI[1602:303] (
0 CoreFoundation 0x00007fff8494225c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8b94fe75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8494512d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff848a0272 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8489fdf8 _CF_forwarding_prep_0 + 120
5 UI 0x0000000100001f01 -[MyScene mouseDown:] + 257
6 SpriteKit 0x0000000100016a05 -[SKView mouseDown:] + 374
7 AppKit 0x00007fff8d12aa58 -[NSWindow sendEvent:] + 11296
8 AppKit 0x00007fff8d0c95d4 -[NSApplication sendEvent:] + 2021
9 AppKit 0x00007fff8cf199f9 -[NSApplication run] + 646
10 AppKit 0x00007fff8cf04783 NSApplicationMain + 940
11 UI 0x0000000100002042 main + 34
12 libdyld.dylib 0x00007fff8ceef5fd start + 1
13 ??? 0x0000000000000003 0x0 + 3
)
答案 0 :(得分:1)
您的按钮由一组对象组成:形状,文本和文本阴影。我假设您希望代码调用setIsPressed,如果任何用户选择了其中一个对象。目前,您的代码仅检查是否选择了形状(这导致错误,因为SKShape没有名为isPressed的属性)。我建议你概括你的代码,以便处理所有情况。这是一种方法:
-(void)mouseDown:(NSEvent *)theEvent {
CGPoint location = [theEvent locationInNode:self];
// Search all nodes at location for a Button
NSArray *nodes = [self nodesAtPoint:location];
for (SKNode *node in nodes) {
if ([node isKindOfClass:[Button class]]) {
[((Button *)node) setIsPressed];
break;
}
}
}
另外,也许Button应该是SKNode的子类而不是SKSpriteNode。