@interface UIDraggableImageView : UIImageView {
}
.m файл
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
// Retrieve the touch point
CGPoint point = [[touches anyObject] locationInView:self];
startLocation = point;
[[self superview] bringSubviewToFront:self];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
// Move relative to the original touch point
CGPoint point = [[touches anyObject] locationInView:self];
CGRect frame = [self frame];
frame.origin.x += point.x - startLocation.x;
frame.origin.y += point.y - startLocation.y;
[self setFrame:frame];
}
удалил этот код из Интернета для перетаскиваемого изображения,
Проблема: изображение неправильной формы с прозрачными областями, при перетаскивании по прозрачным областямэто также.
Требуемое решение: Как сделать прозрачные области не интерактивными / не перетаскиваемыми?
Любые предложения, я попытаюсь замаскировать изображение как попытку и опубликую результаты, но любые обходные пути / совет.
В дополнение к предложениям MiRAGe: Попытка включить код в один файл класса, так как свойство изображения доступно в UIImageView, и было бы проще подключить и играть с любым UIImageView в интерфейсестроитель, но все еще возникают проблемы, прозрачные области являются подвижными, метод hitTest вызывается несколько раз одним кликом, любой совет?
#import "UIImageViewDraggable.h"
@implementation UIImageViewDraggable
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Retrieve the touch point
CGPoint point = [[touches anyObject] locationInView:self];
startLocation = point;
[[self superview] bringSubviewToFront:self];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
// Move relative to the original touch point
CGPoint point = [[touches anyObject] locationInView:self];
CGRect frame = [self frame];
frame.origin.x += point.x - startLocation.x;
frame.origin.y += point.y - startLocation.y;
[self setFrame:frame];
}
- (NSData *)alphaData {
CGContextRef cgctx = NULL;
void * bitmapData;
int bitmapByteCount;
size_t pixelsWide = CGImageGetWidth(self.image.CGImage);
size_t pixelsHigh = CGImageGetHeight(self.image.CGImage);
bitmapByteCount = (pixelsWide * pixelsHigh);
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
return nil;
cgctx = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8,
pixelsWide,
NULL,
kCGImageAlphaOnly);
if (cgctx == NULL) {
free (bitmapData);
fprintf (stderr, "Context not created!");
return nil;
}
CGRect rect = {{0,0},{pixelsWide,pixelsHigh}};
CGContextDrawImage(cgctx, rect, self.image.CGImage);
unsigned char *data = CGBitmapContextGetData(cgctx);
CGContextRelease(cgctx);
if (!data) {
free(bitmapData);
return nil;
}
size_t dataSize = pixelsWide * pixelsHigh;
NSData *alphaData = [NSData dataWithBytes:data length:dataSize];
free(bitmapData);
return alphaData;
}
- (BOOL)isTransparentLocation:(CGPoint)point withData:(NSData *)data {
if (data == nil)
NSLog(@"data was nil");
NSUInteger index = point.x + (point.y * [self.image size].width);
unsigned char *rawDataBytes = (unsigned char *)[data bytes];
return (rawDataBytes[index] == 0);
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"test");
NSAutoreleasePool *pool = [NSAutoreleasePool new];
// view responding to the hit test. note that self may respond too.
UIView *anyViewResponding = [super hitTest:point withEvent:event];
if( anyViewResponding == nil || anyViewResponding == self ) {
// convert the point in the image, to a global point.
CGPoint framePoint = [self.superview convertPoint:point fromView:self];
// if the point is in the image frame, and there is an image, see if we need to let the touch through or not
if(self.image != nil && CGRectContainsPoint([self frame], framePoint)) {
NSData *imageData = [self alphaData];
// check if the point touched is transparent in the image
if( imageData != nil && [self isTransparentLocation:point withData:imageData]) {
// return nil, so the touch will not arrive at this view
anyViewResponding = nil;
}
}
}
[pool drain];
return anyViewResponding;
}