做一个透明层 [英] Make a see-through layer

查看:84
本文介绍了做一个透明层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的应用上实现擦除功能.对于图像,我可以在使用 UIGraphicsBeginImageContextWithOptions 绘制图像时将弯曲模式设置为清晰.这是我用过的代码

UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0)守卫让上下文 = UIGraphicsGetCurrentContext() else { return }image.draw(in: self.bounds)context.setLineCap(.round)context.setLineWidth(5)context.setStrokeColor(UIColor.white.cgColor)context.setBlendMode(.clear)context.beginPath()context.move(to: lastStroke.touchPoint)context.addLine(to: currentStroke.touchPoint)上下文.strokePath()让 updatedImage = UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()

它适用于图像.但我想在 UILabel 上实现它.

可以实现的一种方法是将UILabel 转换为UIImage,这会增加UILabel 修改的难度(例如更改字体、间距).这也将使其恢复.

是否可以制作一个可以透视的CALayer/CAShapeLayerUIView?

解决方案

所有视图都有一个Backing layer",包括 UILabel 视图.

因此,您可以在视图层上安装遮罩层.您可以将该蒙版图层设为 CAShapeLayer,或将 CGImage 作为其内容的常规图层.

不要弄乱混合模式.只需向任何图层添加一个遮罩层,您希望能够擦除/取消擦除,包括 UILabel 的图层

遮罩层将显示/隐藏其遮罩层的内容.(蒙版中的不透明像素显示下面的图层,但清晰的像素隐藏它.)

如果您希望能够徒手擦除/显示标签等内容,我建议您使用带有图像的图层作为蒙版.将不透明像素绘制到遮罩图像中以取消擦除"蒙版图像,并使用清晰像素绘制以擦除蒙版图像.因为您只是更改蒙版,所以蒙版图像保持不变.

@IBOutlet 标签:UILabelvar labelMask = CALayer()

...

func viewDidAppear(animated: Bool) {super.viewDidAppear(动画)//将遮罩设置为与标签视图大小相同labelMask.frame = label.boundslabel.layer.mask = labelMasklabelMask.contents =//安装一个 UIImage 的 CGImage 作为内容//其余的 viewDidAppear 代码放在这里...}

I am trying to implement erase functionality on my app. For image I can do it with setting bend mode into clear while drawing image with UIGraphicsBeginImageContextWithOptions. Here is the code I have used

UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return }
image.draw(in: self.bounds)
context.setLineCap(.round)
context.setLineWidth(5)
context.setStrokeColor(UIColor.white.cgColor)
context.setBlendMode(.clear)
context.beginPath()
context.move(to: lastStroke.touchPoint)
context.addLine(to: currentStroke.touchPoint)
context.strokePath()
let updatedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

It works fine for images. But I want to implement it on UILabel.

One way it can be achieved is by converting UILabel into an UIImage which will increase difficulty for UILabel modification(e.g. change font, spacing). Also this will make it rester.

Is it possible to make a CALayer/ CAShapeLayer or UIView which can be see-through?

Here is an example I have seen on an app.

P.S: I am not looking for exact code, any implementation idea will be appreciable.

解决方案

All views have a "Backing layer", including UILabel views.

As such, you can install a mask layer on the view's layer. You can make that mask layer a CAShapeLayer, or a regular layer with a CGImage as it's contents.

Don't mess with blend modes. Just add a mask layer to any layer that you want to be able to erase/un-erase, including a UILabel's layer

The mask layer will show/hide the contents of the layer it masks. (Opaque pixels in the mask reveal the layer underneath, but clear pixels hide it.)

If you want to be able to do freehand erasing/revealing of things like labels, I would suggest using a layer with an image in it as your mask. Draw opaque pixels into the masks image to "un-erase" the masked image, and draw with clear pixels to erase the masked image. Because you're just changing the mask, the masked image is left untouched.

@IBOutlet label: UILabel
var labelMask = CALayer()

...

func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    // Set up the mask to be the same size as the label view
    labelMask.frame = label.bounds
    label.layer.mask = labelMask
    labelMask.contents = // install a UIImage's CGImage as the contents
    // The rest of your viewDidAppear code goes here...
}

Edit:

I posted a demo app on Github it that illustrates how to mask ANY view using a CALayer. This demo app uses a CGImage to create a raster mask. You can also use a CAShapeLayer as a vector mask.

Here is the readme from that project:


MaskableImageView

This project demonstrates how to use a CALayer to mask a UIView.

It defines a custom subclass of UIImageView, MaskableView.

The MaskableView class has a property maskLayer that contains a CALayer.

MaskableView defines a didSet method on its bounds property so that when the view's bounds change, it resizes the mask layer to match the size of the image view.

The MaskableView has a method installSampleMask which builds an image the same size as the image view, mostly filled with opaque black, but with a small rectangle in the center filled with black at an alpha of 0.7. The translucent center rectangle causes the image view to become partly transparent and show the view underneath.

The demo app installs a couple of subviews into the MaskableView, a sample image of Scampers, one of my dogs, and a UILabel. It also installs an image of a checkerboard under the MaskableView so that you can see the translucent parts more easily.

The MaskableView has properties circleRadius, maskDrawingAlpha, and drawingAction that it uses to let the user erase/un-erase the image by tapping on the view to update the mask.

The MaskableView attaches a UIPanGestureRecognizer and a UITapGestureRecognizer to itself, with an action of gestureRecognizerUpdate. The gestureRecognizerUpdate method takes the tap/drag location from the gesture recognizer and uses it to draw a circle onto the image mask that either decreases the image mask's alpha (to partly erase pixels) or increase the image mask's alpha (to make those pixels more opaque.)

The MaskableView's mask drawing is crude, and only meant for demonstration purposes. It draws a series of discrete circles intstead of rendering a path into the mask based on the user's drag gesture. A better solution would be to connect the points from the gesture recognizer and use them to render a smoothed curve into the mask.

The app's screen looks like this:

这篇关于做一个透明层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆