84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
比如说A是一个imageView,B仅仅是一个普通的透明的view,我希望A被B盖住的部分是彩色的,而没有盖住的部分是黑白的,请问有什么实现的思路吗
业精于勤,荒于嬉;行成于思,毁于随。
可以控制A的layer.mask实现,mask即为A和B的重合区域,通过计算重合区域的rect来改变layer.mask的填充path。很多遮罩效果都是用mask实现的。
layer.mask
rect
path
我写了一份代码,你可以参考一下。直接在playground上就可以看到效果了:
import UIKit import PlaygroundSupport /// 可以拖动的View,即ViewB class DragableView:UIView { var maskLayer: CAShapeLayer? var viewThatMask: UIView? { didSet { maskLayer?.removeFromSuperlayer() maskLayer = nil if let _ = viewThatMask { self.maskLayer = CAShapeLayer() self.maskLayer?.backgroundColor = UIColor.orange.cgColor self.maskLayer?.frame = self.bounds self.layer.mask = self.maskLayer } } } override init(frame: CGRect) { super.init(frame: frame) self.isOpaque = true self.backgroundColor = .black let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGestureEvent(_:))) self.addGestureRecognizer(gesture) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } /// 相交部分改变的处理闭包, 参数rect是相交的区域, view是maskView var maskChangedHandler:((CGRect, UIView)->Void)? func panGestureEvent(_ gesture:UIPanGestureRecognizer) { let point = gesture.translation(in: self) if gesture.state == .changed { self.frame.origin.x += point.x self.frame.origin.y += point.y gesture.setTranslation(.zero, in: self) if let viewThatMask = self.viewThatMask, let superview = self.superview { // 两个View相交rect,以父view为参考 let rectInSuper = self.frame.intersection(viewThatMask.frame) // 转化为以图片的坐标系的rect let interRectInMask = superview.convert(rectInSuper, to: viewThatMask) if let maskChangedHandler = self.maskChangedHandler { maskChangedHandler(interRectInMask, viewThatMask) } } } } } let imageViewColorful = UIImageView(frame: CGRect(x:50, y:50, width:150, height:100)) imageViewColorful.image = UIImage(named: "dog_colorful") imageViewColorful.layer.mask = CAShapeLayer() let imageViewGray = UIImageView(frame: CGRect(x:50, y:50, width:150, height:100)) imageViewGray.image = UIImage(named: "dog_gray") let dragView = DragableView(frame: CGRect(x:50, y:200, width:200, height:200)) dragView.viewThatMask = imageViewColorful dragView.maskChangedHandler = { rect, viewA in if let maskLayer = viewA.layer.mask as? CAShapeLayer { maskLayer.path = CGPath(rect: rect, transform: nil) maskLayer.fillColor = UIColor.black.cgColor } } let view = UIView(frame: CGRect(x:0, y:0, width:400, height:640)) view.backgroundColor = .white view.addSubview(dragView) view.addSubview(imageViewGray) view.addSubview(imageViewColorful) PlaygroundPage.current.liveView = view
如果运行正常的话,可以在playground的Assistant Editor中看到如下效果:
1.计算出AB相交部分的size2.计算出彩色部分的起点3.运用贝塞尔曲线画出彩色部分4.运用CAShapeLayer将path设置为第三步的贝塞尔曲线,将layer添加到A上.
个人想法,可以试试.
可以控制A的
layer.mask
实现,mask即为A和B的重合区域,通过计算重合区域的rect
来改变layer.mask
的填充path
。很多遮罩效果都是用mask实现的。我写了一份代码,你可以参考一下。直接在playground上就可以看到效果了:
如果运行正常的话,可以在playground的Assistant Editor中看到如下效果:
1.计算出AB相交部分的size
2.计算出彩色部分的起点
3.运用贝塞尔曲线画出彩色部分
4.运用CAShapeLayer将path设置为第三步的贝塞尔曲线,将layer添加到A上.
个人想法,可以试试.