Ios 使用Sprite工具包创建自定义滑块-如何传递@selector?
我正在开发的一款精灵套件游戏使用自定义滑块作为颜色选择器(颜色从滑块轨迹图形中拾取,该图形是包含渐变的Ios 使用Sprite工具包创建自定义滑块-如何传递@selector?,ios,objective-c,selector,sprite-kit,Ios,Objective C,Selector,Sprite Kit,我正在开发的一款精灵套件游戏使用自定义滑块作为颜色选择器(颜色从滑块轨迹图形中拾取,该图形是包含渐变的UIImage) 我考虑过使用定制的UISlider,但是标准的IOS UI控件不能很好地与Sprite Kit的场景配合使用:它们很难相对于场景的其余部分进行定位(因为它们是作为主视图的子视图而不是作为SKScene的一部分存在),它们会突然出现(而不是与场景的其余部分过渡)并且在退出场景时必须手动删除。简言之,实现它们是一件痛苦的事情,而且它们无法无缝集成 我已经开始使用SKSpriteNo
UIImage
)
我考虑过使用定制的UISlider
,但是标准的IOS UI控件不能很好地与Sprite Kit的场景配合使用:它们很难相对于场景的其余部分进行定位(因为它们是作为主视图的子视图而不是作为SKScene
的一部分存在),它们会突然出现(而不是与场景的其余部分过渡)并且在退出场景时必须手动删除。简言之,实现它们是一件痛苦的事情,而且它们无法无缝集成
我已经开始使用SKSpriteNode
s实现自定义滑块,在的基础上构建,并将滑块轨迹和手柄放置到位。手柄沿轨迹左右滑动,并将值设置在0和1之间(就像UISlider
)。我调用了此类SKSlider
我想做的是传递SKSlider
一个@选择器
,方式与传递UISlider
的方式大致相同,因此我可以在SKScene
中定义一个函数,以便滑块执行:
[mySlider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
滑块更改时我尝试调用的函数如下所示:
-(UIColor*)getRGBAFromImage:(UIImage*)image atX:(float)xp atY:(float)yp
{
NSMutableArray *resultColor = [NSMutableArray array];
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
int byteIndex = (bytesPerRow * yp) + xp * bytesPerPixel;
CGFloat red = (rawData[byteIndex] * 1.0) /255.0;
CGFloat green = (rawData[byteIndex + 1] * 1.0)/255.0 ;
CGFloat blue = (rawData[byteIndex + 2] * 1.0)/255.0 ;
CGFloat alpha = (rawData[byteIndex + 3] * 1.0) /255.0;
byteIndex += 4;
UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
[resultColor addObject:color];
NSLog(@"width:%i hight:%i Color:%@",width,height,[color description]);
free(rawData);
return color;
}
(为感兴趣的人找到了代码。)
但是我不确定应该如何在
SKSlider
的界面中设置此选项。有人能为我指出正确的方向吗?只需在自定义滑块中实现缺少的方法。在界面中添加此选项:
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
在实现中,将目标
和操作
存储为属性
@property (nonatomic, strong) id target;
@property (nonatomic) SEL action;
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
{
_target = target;
_action = action;
}
然后在值更改时对目标调用操作
:
objc_msgSend(_target, _action);
请记住导入:
#import <objc/message.h>
选择器的变量类型是SEL
。以下是如何声明属性以跟踪目标和操作。(请注意,SEL
是指向结构的指针,而不是指向对象的指针,因此指定strong
或弱
将使编译器不安。)
下面是一个更新目标和操作的示例方法
- (void)changeTarget:(id)target action:(SEL)action
{
self.target = target;
self.action = action;
}
这就是对目标调用action方法的方式
[self.target performSelector:self.action withObject:self afterDelay:0.0];
请注意,self是作为参数传递给方法的,因此目标中的方法签名应该是
- (void)someAction:(id)sender
嗯,我想是这样的……但是现在出现了错误:ARC不允许将Objective-C指针隐式转换为'SEL'(也称为'SEL*),而PerformSelector可能会导致泄漏,因为它的选择器未知。
…我仍然收到ARC限制警告,说不允许隐式转换:(我想差不多了!据我所知,我称之为:[skinSlider addTarget:self action:@selector(getRGBAFromImage:atX:atY:)withObject:skinGradient withObject:skinSlider.value withObject:0 forControlEvents:UIControlEventValueChanged];
(传入变量),那么我应该如何更改界面?不要将不应该在滑块中的逻辑放入其中。滑块是一个控件。它应该只进行滑动并将其告知目标。然后,目标对象(可能是您的视图控制器或场景)我更新了我的答案。太棒了。这非常有效,你告诉了我一些新的事情。一千个感谢、投票、接受等等。reecon打败了你(只是),但你的答案也很有用:投票。
[self.target performSelector:self.action withObject:self afterDelay:0.0];
- (void)someAction:(id)sender