<i id='acWRc'><tr id='acWRc'><dt id='acWRc'><q id='acWRc'><span id='acWRc'><b id='acWRc'><form id='acWRc'><ins id='acWRc'></ins><ul id='acWRc'></ul><sub id='acWRc'></sub></form><legend id='acWRc'></legend><bdo id='acWRc'><pre id='acWRc'><center id='acWRc'></center></pre></bdo></b><th id='acWRc'></th></span></q></dt></tr></i><div id='acWRc'><tfoot id='acWRc'></tfoot><dl id='acWRc'><fieldset id='acWRc'></fieldset></dl></div>

      <legend id='acWRc'><style id='acWRc'><dir id='acWRc'><q id='acWRc'></q></dir></style></legend>
      1. <tfoot id='acWRc'></tfoot>
          <bdo id='acWRc'></bdo><ul id='acWRc'></ul>

        <small id='acWRc'></small><noframes id='acWRc'>

      2. 可拖动的 UIImageView 部分透明 &amp;不规则形状

        时间:2024-04-15

            <bdo id='2zhDd'></bdo><ul id='2zhDd'></ul>

            <small id='2zhDd'></small><noframes id='2zhDd'>

              <tbody id='2zhDd'></tbody>
          • <i id='2zhDd'><tr id='2zhDd'><dt id='2zhDd'><q id='2zhDd'><span id='2zhDd'><b id='2zhDd'><form id='2zhDd'><ins id='2zhDd'></ins><ul id='2zhDd'></ul><sub id='2zhDd'></sub></form><legend id='2zhDd'></legend><bdo id='2zhDd'><pre id='2zhDd'><center id='2zhDd'></center></pre></bdo></b><th id='2zhDd'></th></span></q></dt></tr></i><div id='2zhDd'><tfoot id='2zhDd'></tfoot><dl id='2zhDd'><fieldset id='2zhDd'></fieldset></dl></div>
            • <legend id='2zhDd'><style id='2zhDd'><dir id='2zhDd'><q id='2zhDd'></q></dir></style></legend>

              <tfoot id='2zhDd'></tfoot>

                  本文介绍了可拖动的 UIImageView 部分透明 &amp;不规则形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  @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];
                  }
                  

                  将此代码从网络上取下来用于可拖动图像,

                  took this code off the web for the draggable image,

                  问题:图片是不规则形状,有透明区域,点击透明区域也会拖拽.

                  Problem: image is irregular shape with transparent areas, clicking on transparent areas drags it as well.

                  必需的解决方案:如何使透明区域不可交互/不可拖动?

                  Required Solution: How to make the transparent areas non interactive/non draggable?

                  任何建议,我将尝试掩盖图像并发布结果,但任何解决方法/建议.

                  Any suggestions, I will be trying to mask the image as an attempt and will post the results, but any workarounds/advise.

                  MiRAGe 的进一步建议:尝试将代码合并到一个类文件中,因为图像属性在 UIImageView 中可用,并且在界面生成器中使用任何 UIImageView 即插即用会更容易,但仍然存在问题,透明区域是可移动的,hitTest 方法在单击时被多次调用,有什么建议吗?

                  Further to suggestions by MiRAGe: Trying to incorporate the code in one class file, since image property is available in UIImageView and it would be easier to plug and play with any UIImageView in interface builder, but still having problems, transparent areas are movable, hitTest method gets called several times on a single click, any advise?

                  #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;
                  }
                  

                  推荐答案

                  您可以轻松检测 alpha 区域并使其不可拖动.这是一些允许您检测 alpha 区域的代码.这对你来说可能是一些开销,但这是我能做的最好的.

                  You can easily detect alpha area's and make them non draggable. Here is some code that will allow you to detect alpha area's. It might be some overhead for you, but it's the best I could do.

                  我对 UIImage 进行了子类化,并将这段代码放在了实现文件中.

                  I have subclassed UIImage and put this code in the implementation file.

                  #import <CoreGraphics/CoreGraphics.h>
                  
                  - (NSData *)alphaData
                  {
                      CGContextRef    cgctx = NULL;
                      void *          bitmapData;
                      int             bitmapByteCount;
                  
                      size_t pixelsWide = CGImageGetWidth(self.CGImage);
                      size_t pixelsHigh = CGImageGetHeight(self.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.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 size].width);
                      unsigned char *rawDataBytes = (unsigned char *)[data bytes];
                  
                      return (rawDataBytes[index] == 0);
                  }
                  

                  现在在 UIImageView 的子类中(我使用 hitTest 函数来允许检测,但您可以轻松地将其更改为适合您的东西,这只是一个示例)我放置此代码来检测点命中是否透明或不.如果它是透明的,我们将触摸传递给下面的视图,否则我们将触摸保留给自己.

                  Now in a subclass of UIImageView (I use the hitTest function to allow detection, but you could easily change this into something that works for you, this is just an example) I put this code to detect if the point hit was transparent or not. If it is transparent, we pass the touch onto the view below, otherwise we keep the touch to ourselves.

                  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
                  {
                      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.image alphaData];         
                  
                              // check if the point touched is transparent in the image
                              if( imageData != nil && [self.image isTransparentLocation:point imageData] )
                              {               
                                  // return nil, so the touch will not arrive at this view
                                  anyViewResponding = nil;
                              }
                          }
                      }
                  
                      [pool drain];
                      return anyViewResponding;
                  }
                  

                  这篇关于可拖动的 UIImageView 部分透明 &amp;不规则形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何从 UIImagePickerController 设置保存图像的分辨率 下一篇:创建 UIImage 抠图

                  相关文章

                1. <tfoot id='K8PRD'></tfoot>

                  <small id='K8PRD'></small><noframes id='K8PRD'>

                      <bdo id='K8PRD'></bdo><ul id='K8PRD'></ul>
                    <i id='K8PRD'><tr id='K8PRD'><dt id='K8PRD'><q id='K8PRD'><span id='K8PRD'><b id='K8PRD'><form id='K8PRD'><ins id='K8PRD'></ins><ul id='K8PRD'></ul><sub id='K8PRD'></sub></form><legend id='K8PRD'></legend><bdo id='K8PRD'><pre id='K8PRD'><center id='K8PRD'></center></pre></bdo></b><th id='K8PRD'></th></span></q></dt></tr></i><div id='K8PRD'><tfoot id='K8PRD'></tfoot><dl id='K8PRD'><fieldset id='K8PRD'></fieldset></dl></div>
                    1. <legend id='K8PRD'><style id='K8PRD'><dir id='K8PRD'><q id='K8PRD'></q></dir></style></legend>