簡體   English   中英

用另一個UIView掩蓋UIView

[英]Mask UIView with another UIView

是的,之前已經問過這個問題,解決方案沒有用,或者有不同的應用。

這是最基本的設置。 我有兩個矩形的UIViews,紅色和藍色。 我希望藍色方塊切入紅色方塊,所以紅色方塊看起來像一個“L”

在此輸入圖像描述

import Foundation
import UIKit

class TestController: UIViewController {
    override func viewDidLoad() {
        view.backgroundColor = .gray
        view.addSubview(viewA)
        view.addSubview(maskView)

        viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
        viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
        viewA.translatesAutoresizingMaskIntoConstraints = false

        maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
        maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
        maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
        maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
        maskView.translatesAutoresizingMaskIntoConstraints = false

        // Things which don't work
        //viewA.mask = maskView // both views disappear
        //viewA.layer.mask = maskView.layer // both views disappear
        //viewA.layer.addSublayer(maskView.layer) // hides mask view
    }

    var viewA: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        view.layer.masksToBounds = true
        return view
    }()

    var maskView: UIView = {
        let view = UIView()
        view.backgroundColor = .blue
        return view
    }()
}

這是我期待的結果:(在Photoshop中完成)

在此輸入圖像描述

由於沒有神奇的方法來掩蓋iOS中的方式,我在這里提出了一種實現這一目標的簡單方法。

不要忘記平移區域,如果離開紅色方塊,它將變成藍色方塊。

為自己的目的修改UIViews的子類並不難,特別是視圖。

    import UIKit

        class TestController: UIViewController {

                override func viewDidLoad() {
                    view.backgroundColor = .gray
                    view.addSubview(viewA)
                    view.addSubview(maskView)
                    maskView.maskedView = viewA
                    viewA.activeMask = maskView
                    viewA.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
                    viewA.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
                    viewA.widthAnchor.constraint(equalToConstant: 100).isActive = true
                    viewA.heightAnchor.constraint(equalToConstant: 100).isActive = true
                    viewA.translatesAutoresizingMaskIntoConstraints = false
                    maskView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 50).isActive = true
                    maskView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50).isActive = true
                    maskView.widthAnchor.constraint(equalToConstant: 100).isActive = true
                    maskView.heightAnchor.constraint(equalToConstant: 100).isActive = true
                    maskView.translatesAutoresizingMaskIntoConstraints = false
                }

                var viewA: MyUIView = {
                    let view = MyUIView()
                    view.backgroundColor = .clear
                    view.layer.masksToBounds = true
                    return view
                }()


            var maskView: ActiveMaskView = {
                let view = ActiveMaskView()
                    view.backgroundColor = .clear
                    return view
                }()


            }

        class ActiveMaskView: UIView{
            override func didMoveToSuperview() {
                super.didMoveToSuperview()
                let panGesture =  UIPanGestureRecognizer.init(target: self, action: #selector(moveAround(_:)))
                self.addGestureRecognizer(panGesture)
            }
              weak  var maskedView : UIView?
            private var frameOrigin : CGPoint = CGPoint.zero

          @objc  func moveAround(_ panGesture: UIPanGestureRecognizer){
            guard let superview = superview else {return}
                switch panGesture.state {
                case .began:
                  frameOrigin = frame.origin
                    self.backgroundColor = UIColor.blue
                case .changed:
                    let translation  = panGesture.translation(in: superview)
                    frame = CGRect.init(origin: CGPoint.init(x: frameOrigin.x + translation.x, y: frameOrigin.y + translation.y), size: frame.size)
                    maskedView?.setNeedsDisplay()
                    break
                case .ended:
                    self.backgroundColor =
                        frame.intersects(maskedView!.frame) ?
                    UIColor.clear : UIColor.blue
                    maskedView?.setNeedsDisplay()
                case .cancelled:
                    frame = CGRect.init(origin: frameOrigin , size: frame.size)
                    self.backgroundColor =
                        frame.intersects(maskedView!.frame) ?
                    UIColor.clear : UIColor.blue
                    maskedView?.setNeedsDisplay()
                default:
                    break;
                }
            }
        }

        class MyUIView: UIView{

          weak  var activeMask: ActiveMaskView?

            override func draw(_ rect: CGRect) {
                super.draw(rect)
                let ctx = UIGraphicsGetCurrentContext()
                ctx?.setFillColor(UIColor.red.cgColor)
                ctx?.fill(self.layer.bounds)
                ctx?.setBlendMode(.sourceOut)
                guard let activeMask = activeMask , let superview = superview else {
                   return
                }
              let sc = frame.intersection(activeMask.frame)
            let interSection = superview.convert(sc, to: self)
                ctx?.fill(interSection )
             }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM