2014-03-06 43 views
2

我正在使用的Sprite Kit遊戲使用自定義滑塊來充當顏色選擇器(顏色從滑塊軌道圖形中挑選,這是一個包含漸變的UIImage)。使用Sprite Kit創建自定義滑塊 - 如何傳遞一個@selector?

我使用自定義的UISlider進行了研究,但標準IOS UI控件在Sprite Kit的場景中播放不好:它們很難相對於場景的其餘部分進行定位(因爲它們作爲主體的子視圖存在觀看而不是作爲SKScene的一部分),它們會彈出存在(而不是與場景的其餘部分過渡),並且必須在退出場景時手動移除。簡而言之,實施它們是一種痛苦,而且它們不能無縫集成。

我已經開始使用SKSpriteNode s實現自定義滑塊,建立在Grafexcellent SKButton class上,並且具有滑塊軌道和手柄。手柄沿着軌道左右滑動,並將值設置爲0到1之間(就像UISlider一樣)。我稱這個類爲SKSlider

我想這樣做的是通過SKSlider一個@selector,在大致相同的方式,你會一個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;   
} 

(代碼被發現here,對於那些有興趣)

但我不確定我應該如何在SKSlider的界面中設置它。有人能指出我正確的方向嗎?

回答

1

只需在自定義滑塊中實現缺少的方法。在界面中添加此:

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; 

而且在實施店鋪targetaction的性能。

@property (nonatomic, strong) id target; 
@property (nonatomic) SEL action; 

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents 
{ 
    _target = target; 
    _action = action; 
} 

然後調用一個target值發生變化時action

objc_msgSend(_target, _action); 

記得導入:

#import <objc/message.h> 

然後得到從滑塊更新創建valueChanged方法,並添加它:

- (void)valueChanged 
{ 
    CGFloat value = _yourSlider.value; 
    // Do something with the value. 
} 

[_yourSlider addTarget:self action:@selector(valueChanged) forControlEvents: UIControlEventValueChanged]; 
+0

嗯,到了那裏我想......但它現在出現了錯誤:'將Objective-C指針隱式轉換爲'SEL'(又名'SEL *')不允許使用ARC並且'PerformSelector可能導致泄漏,因爲它的選擇器是未知的...... – MassivePenguin

+0

我更新了我的答案。檢查出來:) – RaffAl

+0

我仍然得到ARC限制警告說隱式轉換是不允許的:( – MassivePenguin

2

選擇器的變量類型爲SEL。以下說明如何聲明屬性以跟蹤目標和操作。 (請注意,SEL是指向結構的指針,而不是指向對象的指針,因此指定strongweak會使編譯器不安。)

@property (nonatomic, strong) id target; 
@property (nonatomic) SEL action; 

下面是更新目標和行動

- (void)changeTarget:(id)target action:(SEL)action 
{ 
    self.target = target; 
    self.action = action; 
} 

的樣品的方法這就是你怎麼罵目標上的操作方法

[self.target performSelector:self.action withObject:self afterDelay:0.0]; 

注意自我作爲傳遞該方法的一個論據,因此目標中的方法簽名應該是

- (void)someAction:(id)sender 
+0

reecon擊敗你(只),但你的答案也很有用:upvoted。 – MassivePenguin