objective-c - iOS imageView渲染的问题
迷茫
迷茫 2017-04-18 09:46:29
0
2
622

比如说A是一个imageView,B仅仅是一个普通的透明的view,我希望A被B盖住的部分是彩色的,而没有盖住的部分是黑白的,请问有什么实现的思路吗

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(2)
黄舟

可以控制A的layer.mask实现,mask即为A和B的重合区域,通过计算重合区域的rect来改变layer.mask的填充path。很多遮罩效果都是用mask实现的。

我写了一份代码,你可以参考一下。直接在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相交部分的size
2.计算出彩色部分的起点
3.运用贝塞尔曲线画出彩色部分
4.运用CAShapeLayer将path设置为第三步的贝塞尔曲线,将layer添加到A上.

个人想法,可以试试.

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板