0

假设您想实现与 iOS 的相机“缩放和裁剪”相同的功能……您可以在其中滚动和裁剪图像。

图片中超出裁剪区域大小的任何部分都会变灰。我正在尝试完全复制这一点。如果标志“clipToBounds”设置为 NO,则可以显示整个子视图。

但是,我发现将 UIScrollView 的子视图溢出变灰有点困难。

你将如何实施?提前致谢!

4

2 回答 2

3

您可以通过UIView在溢出区域中创建一个半透明且在“裁剪”区域中透明的子类并将其放置在您的上方并将其UIScrollView扩展以覆盖溢出来做到这一点。

您需要实现的主要方法是initWithFrame

#define kIDZAlphaOverlayDefaultAlpha 0.75

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        mAlpha = kIDZAlphaOverlayDefaultAlpha;
        self.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:mAlpha];
        self.userInteractionEnabled = NO;
    }
    return self;
}

不要错过,userInteractionEnabled = NO否则滚动视图将看不到事件。

drawRect

- (void)drawRect:(CGRect)rect
{    
    CGRect apertureRect = /* your crop rect */;
    CGContextRef context = UIGraphicsGetCurrentContext();
    /* draw the transparent rect */
    CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.0);
    CGContextSetBlendMode(context, kCGBlendModeCopy);
    CGContextFillRect(context, apertureRect);
    /* draw a white border */
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextStrokeRect(context, apertureRect);
}

这里重要的一点是,kCGBlendModeCopy这允许我们在半透明背景中绘制(或剪切)一个透明矩形。

如果您想将透明矩形设为圆角矩形,并包含裁剪图像的预览,最终会得到如下屏幕所示的内容:

IDZAlphaOverlay 运行中的屏幕截图

抱歉,我无法分享屏幕截图的所有代码。它来自一个客户项目:-(

于 2012-07-13T00:59:21.250 回答
0

我已经通过...解决了这个问题:

  • 添加一个新的帮助类,“ApertureOverlay”(UIView 的子类),代码如下:

    • (void)drawRect:(CGRect)rect {

      if(CGRectEqualToRect(_apertureRect, CGRectZero) == NO)

      {

      CGContextRef context = UIGraphicsGetCurrentContext();
      
      CGContextSetShouldAntialias(context, false);
      
      CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f);
      CGContextFillRect(context, _apertureRect);
      
      CGContextSetShouldAntialias(context, true);
      

      }

    }

  • ApertureOverlay 有一个背景,其 alpha 字节设置为 50%。

    [self setBackgroundColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.5f]];

到目前为止...我们得到的是一个具有透明背景的视图和一个白色矩形(使用 _apertureRect 位置 + 大小绘制)。

在实现了这个类之后,我设置了 ScrollView 的 'mask' 属性,它包含了里面的图像。

[[self layer] setMask:[_apertureOverlayView layer]];

就是这样!。如果您更新 ApertureOverlay 的“_apertureRect”属性,则需要调用“setNeedsDisplay”,以便重新绘制。

还有一件事。通过将抗锯齿设置为假(ApertureOverlay)......事情工作得非常顺利。

于 2012-07-18T22:42:51.607 回答