假设您想实现与 iOS 的相机“缩放和裁剪”相同的功能……您可以在其中滚动和裁剪图像。
图片中超出裁剪区域大小的任何部分都会变灰。我正在尝试完全复制这一点。如果标志“clipToBounds”设置为 NO,则可以显示整个子视图。
但是,我发现将 UIScrollView 的子视图溢出变灰有点困难。
你将如何实施?提前致谢!
假设您想实现与 iOS 的相机“缩放和裁剪”相同的功能……您可以在其中滚动和裁剪图像。
图片中超出裁剪区域大小的任何部分都会变灰。我正在尝试完全复制这一点。如果标志“clipToBounds”设置为 NO,则可以显示整个子视图。
但是,我发现将 UIScrollView 的子视图溢出变灰有点困难。
你将如何实施?提前致谢!
您可以通过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
这允许我们在半透明背景中绘制(或剪切)一个透明矩形。
如果您想将透明矩形设为圆角矩形,并包含裁剪图像的预览,最终会得到如下屏幕所示的内容:
抱歉,我无法分享屏幕截图的所有代码。它来自一个客户项目:-(
我已经通过...解决了这个问题:
添加一个新的帮助类,“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)......事情工作得非常顺利。