png прозрачность регистрации сенсорного события iphone?
У меня есть три PNG "320 х 480 пикселей", которые я загружаю в отдельные UIImageViews. Имена PNG - тело, рот, шляпа. Складывая изображения друг на друга, я создаю персонажа, чьи части тела можно легко поменять местами. Смотрите фото>
http://www.1976inc.com/dev/iphone/beast.jpg
Моя проблема в том, что когда вы касаетесь самого верхнего UIImageView, все изображение, включая прозрачность, регистрирует событие касания. Я хотел бы сделать так, чтобы сенсорные события регистрировались только на непрозрачных частях png. Поэтому сделайте так, чтобы пользователь мог взаимодействовать со всеми тремя UIImageViews.
Я уверен, что это просто, но я новичок в разработке для iphone, и я не могу понять это.
Обновление Итак, я понял, что самый простой способ сделать то, что я хочу сделать, это создать цикл и создать контекст для каждого PNG, а затем получить данные о цвете для пикселей, где произошло событие касания. Если пиксель представляет прозрачную область, я перехожу к следующему изображению и пробую то же самое. Это работает, но только в первый раз. Например, в первый раз, когда я нажимаю на главном экране, я получаю этот вывод
2010-07-26 15: 50: 06.285 colorTest [21501: 207] hat
2010-07-26 15: 50: 06.286 colorTest [21501: 207] смещение: 227024 цвета: RGB A 0 0 0 0
2010-07-26 15:50:06.293 colorTest[21501:207] рот
2010-07-26 15:50:06.293 colorTest[21501:207] смещение: 227024 цвета: RGB A 0 0 0 0
2010-07-26 15: 50: 06.298 colorTest [21501: 207] body
2010-07-26 15: 50: 06.299 colorTest [21501: 207] смещение: 227024 цвета: RGB A 255 255 255 255
это именно то, что я хотел бы увидеть. Но если я снова нажму на ту же область, я получу.
2010-07-26 15: 51: 21.625 colorTest [21501: 207] hat
2010-07-26 15: 51: 21.626 colorTest [21501: 207] смещение: 283220 цветов: RGB A 255 255 255 255
2010-07-26 15:51:21.628 colorTest[21501:207] рот
2010-07-26 15:51:21.628 colorTest[21501:207] смещение: 283220 цветов: RGB A 255 255 255 255
2010-07-26 15: 51: 21.630 colorTest [21501: 207] body
2010-07-26 15: 51: 21.631 colorTest [21501: 207] смещение: 283220 цветов: RGB A 255 255 255 255
Вот код, который я использую;
событие касания существует в mainView для приложения
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touched balls");
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
UIColor *transparent = [UIColor colorWithRed:0 green:0 blue:0 alpha:0];
for( viewTest *currentView in imageArray){
//UIColor *testColor = [self getPixelColorAtLocation:point image:currentView.image];
[currentView getPixelColorAtLocation:point];
}
}
Он вызывает метод в пользовательском классе, который расширяет imageView. Функция возвращает цвет пикселя в touchEvent.
- (UIColor*) getPixelColorAtLocation:(CGPoint)point
{
UIColor *color = nil;
CGImageRef inImage = self.image.CGImage;
CGContextRef context = [self createARGBBitmapContextFromImage:inImage];
if(context == NULL) return nil;
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(context, rect, inImage);
// Now we can get a pointer to the image data associated with the bitmap
// context.
unsigned char* data = CGBitmapContextGetData (context);
if (data != NULL) {
//offset locates the pixel in the data from x,y.
//4 for 4 bytes of data per pixel, w is width of one row of data.
int offset = 4*((w*round(point.y))+round(point.x));
int alpha = data[offset];
int red = data[offset+1];
int green = data[offset+2];
int blue = data[offset+3];
NSLog(@"%@",name);
NSLog(@"offset: %i colors: RGB A %i %i %i %i ",offset,red,green,blue,alpha);
color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
}
// When finished, release the context
CGContextRelease(context);
// Free image data memory for the context
if (data) { free(data); }
return color;
}
- (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = CGImageGetWidth(inImage);
size_t pixelsHigh = CGImageGetHeight(inImage);
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();//CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
CGColorSpaceRelease( colorSpace );
return NULL;
}
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
if (context == NULL)
{
free (bitmapData);
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
}
Обновление 2 Спасибо за быстрый ответ. Я не уверен, что пойду за тобой. Если я изменю скрытый на true, тогда "слой" UIImageView будет скрыт. Я хочу, чтобы прозрачная часть png не регистрировала сенсорные события. Так, например, если вы посмотрите на изображение, которое я включил в пост. Если вы щелкнете по червю, стеблю или листьям, которые являются "частью одного и того же png", событие касания запускается этим ImageView, но если вы касаетесь круга, то событие касания запускается этим ImageView. Кстати, вот код, который я использую, чтобы разместить их в представлении.
UIView *tempView = [[UIView alloc] init];
[self.view addSubview:tempView];
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"body.png"] ];
[imageView1 setUserInteractionEnabled:YES];
UIImageView *imageView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mouth.png"] ];
[imageView2 setUserInteractionEnabled:YES];
UIImageView *imageView3 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"hat.png"] ];
[imageView3 setUserInteractionEnabled:YES];
[tempView addSubview:imageView1];
[tempView addSubview:imageView2];
[tempView addSubview:imageView3];
[self.view addSubview:tempView];
1 ответ
Прежде всего:
Вы можете использовать прозрачность, но скрытие изображения, вероятно, будет соответствовать вашим потребностям.
Вы можете скрыть изображение с помощью следующей команды: [myImage setHidden:YES];
или же myImage.hidden = YES;
if (CGRectContainsPoint(myImage.frame, touchPosition)==true && myImage.hidden==NO)
{
}
Это гарантирует, что ваше изображение не прозрачно при нажатии, потому что myImage.hidden==NO
проверяет, является ли изображение скрытым или нет.