[英]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.