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

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

迷茫
迷茫

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

reply all(2)
黄舟

can control A’slayer.mask实现,mask即为A和B的重合区域,通过计算重合区域的rect来改变layer.mask的填充path. Many masking effects are achieved using masks.

I wrote a code, you can refer to it. You can see the effect directly on the 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

If it runs normally, you can see the following effect in the Assistant Editor of the playground:

大家讲道理

1. Calculate the size of the AB intersection part
2. Calculate the starting point of the colored part
3. Use Bezier curve to draw the colored part
4. Use CAShapeLayer to set the path to the Bezier curve in the third step, and Add layer to A.

Personal idea, you can try it.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template