从 Swift 中的另一个 UIView 中减去 UIView
Subtract UIView from another UIView in Swift
我确信这是一件非常简单的事情,但我似乎无法理解其中的逻辑。
我有两个 UIView。一个黑色、半透明和 "full-screen" ("overlayView"),另一个在顶部,较小且可调整大小 ("cropView")。这几乎是一个裁剪视图设置,我想 "dim" 排除未裁剪的底层图像区域。
我的问题是:我该怎么做?我确定我的方法应该使用 CALayers 和蒙版,但无论我尝试什么,我都无法理解逻辑。
这是我现在拥有的:
这就是我想要的样子:
如何在 Swift 中获得此结果?
可能还有其他绘图解决方案,但基本上您有 4 个区域需要处理。取 space 上方和下方的正方形区域的全宽,并在它们之间添加左右两侧,并相互约束。
虽然您找不到subtract(...)
这样的方法,但您可以使用以下代码轻松构建带有覆盖和透明切割的屏幕:
Swift 4.2
private func addOverlayView() {
let overlayView = UIView(frame: self.bounds)
let targetMaskLayer = CAShapeLayer()
let squareSide = frame.width / 1.6
let squareSize = CGSize(width: squareSide, height: squareSide)
let squareOrigin = CGPoint(x: CGFloat(center.x) - (squareSide / 2),
y: CGFloat(center.y) - (squareSide / 2))
let square = UIBezierPath(roundedRect: CGRect(origin: squareOrigin, size: squareSize), cornerRadius: 16)
let path = UIBezierPath(rect: self.bounds)
path.append(square)
targetMaskLayer.path = path.cgPath
// Exclude intersected paths
targetMaskLayer.fillRule = CAShapeLayerFillRule.evenOdd
overlayView.layer.mask = targetMaskLayer
overlayView.clipsToBounds = true
overlayView.alpha = 0.6
overlayView.backgroundColor = UIColor.black
addSubview(overlayView)
}
只需在自定义视图的构造函数或 ViewController 的 viewDidLoad()
.
中调用此方法
演练
首先我创建了一个原始的 overlayView,然后是我称之为 "targetMaskLayer" 的 CAShapeLayer。最终目标是在 overlayView 内借助 UIBezierPath 绘制一个正方形。定义正方形的尺寸后,我将其 cgPath
设置为 targetMaskLayer 的路径。
现在是重要的部分:
targetMaskLayer.fillRule = CAShapeLayerFillRule.evenOdd
这里我基本上配置了填充规则排除交集
最后,我为 overlayView 提供了一些样式并将其添加为子视图。
ps.: 别忘了import UIKit
我确信这是一件非常简单的事情,但我似乎无法理解其中的逻辑。
我有两个 UIView。一个黑色、半透明和 "full-screen" ("overlayView"),另一个在顶部,较小且可调整大小 ("cropView")。这几乎是一个裁剪视图设置,我想 "dim" 排除未裁剪的底层图像区域。
我的问题是:我该怎么做?我确定我的方法应该使用 CALayers 和蒙版,但无论我尝试什么,我都无法理解逻辑。
这是我现在拥有的:
这就是我想要的样子:
如何在 Swift 中获得此结果?
可能还有其他绘图解决方案,但基本上您有 4 个区域需要处理。取 space 上方和下方的正方形区域的全宽,并在它们之间添加左右两侧,并相互约束。
虽然您找不到subtract(...)
这样的方法,但您可以使用以下代码轻松构建带有覆盖和透明切割的屏幕:
Swift 4.2
private func addOverlayView() {
let overlayView = UIView(frame: self.bounds)
let targetMaskLayer = CAShapeLayer()
let squareSide = frame.width / 1.6
let squareSize = CGSize(width: squareSide, height: squareSide)
let squareOrigin = CGPoint(x: CGFloat(center.x) - (squareSide / 2),
y: CGFloat(center.y) - (squareSide / 2))
let square = UIBezierPath(roundedRect: CGRect(origin: squareOrigin, size: squareSize), cornerRadius: 16)
let path = UIBezierPath(rect: self.bounds)
path.append(square)
targetMaskLayer.path = path.cgPath
// Exclude intersected paths
targetMaskLayer.fillRule = CAShapeLayerFillRule.evenOdd
overlayView.layer.mask = targetMaskLayer
overlayView.clipsToBounds = true
overlayView.alpha = 0.6
overlayView.backgroundColor = UIColor.black
addSubview(overlayView)
}
只需在自定义视图的构造函数或 ViewController 的 viewDidLoad()
.
演练
首先我创建了一个原始的 overlayView,然后是我称之为 "targetMaskLayer" 的 CAShapeLayer。最终目标是在 overlayView 内借助 UIBezierPath 绘制一个正方形。定义正方形的尺寸后,我将其 cgPath
设置为 targetMaskLayer 的路径。
现在是重要的部分:
targetMaskLayer.fillRule = CAShapeLayerFillRule.evenOdd
这里我基本上配置了填充规则排除交集
最后,我为 overlayView 提供了一些样式并将其添加为子视图。
ps.: 别忘了import UIKit