我的 iPad 应用程序中有一张图像,我基本上想在它上面放置一个滤色镜。为此,我有一个彩色 UIView,它被屏蔽为我放在图像上的特定形状。由于调整 Alpha 并没有给我带来想要的效果,我想改用混合模式。
据我所知,您只能在图像上使用混合模式,而不能在普通视图上使用。视图的颜色是动态的,所以我不能只使用图片来代替。
我也尝试将视图光栅化为图像,但这变得全是像素和奇怪的东西,但也许我做错了什么。
所以,基本问题是:是否可以将混合模式应用于视图?或者我应该采取完全不同的方法来达到相同的目标?
查看 CALayer compositingFilter 的文档:https://developer.apple.com/documentation/quartzcore/calayer/1410748-compositingfilter
在颜色叠加视图上,您可以将
view.layer.compositingFilter
设置为 CICategoryCompositeOperation 以实现与其背后内容的混合。这是一些示例游乐场代码,应用了乘法混合模式来测试它(将 UIImage(named: "")
替换为您自己的图像进行测试)
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let mainView = UIView()
self.view = mainView
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false;
image.image = UIImage(named: "maxresdefault.jpg")
mainView.addSubview(image)
let overlay = UIView()
overlay.translatesAutoresizingMaskIntoConstraints = false;
overlay.backgroundColor = .red
overlay.layer.compositingFilter = "multiplyBlendMode"
mainView.addSubview(overlay)
mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": view]))
mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": view]))
mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": overlay]))
mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": overlay]))
}
}
PlaygroundPage.current.liveView = MyViewController()
iOS 13、斯威夫特 5
关键是在适当的 CALayer 上设置
compositingFilter
属性(顶部的那个 - 它与后面的任何内容混合)。颜色混合在 UIView 或 CALayers 之间进行。您可以在这里找到混合模式CICategoryCompositeOperation。要使用过滤器,只需删除 CI
并将名称的第一个字母小写(例如 CIDivideBlendMode
变为 divideBlendMode
)。这是一些游乐场代码来说明:
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 900))
PlaygroundPage.current.liveView = view
let heightIncrement = view.frame.height / 13
let widthIncrement = view.frame.width / 7
// TOP EXAMPLE (UIViews)
let backgroundView = UIView(frame: CGRect(x: widthIncrement * 2,
y: heightIncrement,
width: widthIncrement * 3,
height: heightIncrement * 5))
backgroundView.backgroundColor = .black
view.addSubview(backgroundView)
let overlayView1 = UIView(frame: CGRect(x: widthIncrement,
y: heightIncrement * 2,
width: widthIncrement * 5,
height: heightIncrement))
overlayView1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
overlayView1.layer.compositingFilter = "darkenBlendMode"
view.addSubview(overlayView1)
let overlayView2 = UIView(frame: CGRect(x: widthIncrement,
y: heightIncrement * 4,
width: widthIncrement * 5,
height: heightIncrement))
overlayView2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
overlayView2.layer.compositingFilter = "divideBlendMode"
view.addSubview(overlayView2)
// BOTTOM EXAMPLE (CALayers)
let backgroundLayer = CALayer()
backgroundLayer.frame = CGRect(x: widthIncrement * 2,
y: heightIncrement * 7,
width: widthIncrement * 3,
height: heightIncrement * 5)
backgroundLayer.backgroundColor = UIColor.black.cgColor
view.layer.addSublayer(backgroundLayer)
let overlayLayer1 = CALayer()
overlayLayer1.frame = CGRect(x: widthIncrement,
y: heightIncrement * 8,
width: widthIncrement * 5,
height: heightIncrement)
overlayLayer1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
overlayLayer1.compositingFilter = "darkenBlendMode"
view.layer.addSublayer(overlayLayer1)
let overlayLayer2 = CALayer()
overlayLayer2.frame = CGRect(x: widthIncrement,
y: heightIncrement * 10,
width: widthIncrement * 5,
height: heightIncrement)
overlayLayer2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
overlayLayer2.compositingFilter = "divideBlendMode"
view.layer.addSublayer(overlayLayer2)
结果如下所示:
我确认相同的代码可以在 iOS 中运行。这是视图控制器代码:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let heightIncrement = view.frame.height / 13
let widthIncrement = view.frame.width / 7
// TOP EXAMPLE (UIViews)
let backgroundView = UIView(frame: CGRect(x: widthIncrement * 2,
y: heightIncrement,
width: widthIncrement * 3,
height: heightIncrement * 5))
backgroundView.backgroundColor = .black
view.addSubview(backgroundView)
let overlayView1 = UIView(frame: CGRect(x: widthIncrement,
y: heightIncrement * 2,
width: widthIncrement * 5,
height: heightIncrement))
overlayView1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
overlayView1.layer.compositingFilter = "darkenBlendMode"
view.addSubview(overlayView1)
let overlayView2 = UIView(frame: CGRect(x: widthIncrement,
y: heightIncrement * 4,
width: widthIncrement * 5,
height: heightIncrement))
overlayView2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
overlayView2.layer.compositingFilter = "divideBlendMode"
view.addSubview(overlayView2)
// BOTTOM EXAMPLE (CALayers)
let backgroundLayer = CALayer()
backgroundLayer.frame = CGRect(x: widthIncrement * 2,
y: heightIncrement * 7,
width: widthIncrement * 3,
height: heightIncrement * 5)
backgroundLayer.backgroundColor = UIColor.black.cgColor
view.layer.addSublayer(backgroundLayer)
let overlayLayer1 = CALayer()
overlayLayer1.frame = CGRect(x: widthIncrement,
y: heightIncrement * 8,
width: widthIncrement * 5,
height: heightIncrement)
overlayLayer1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
overlayLayer1.compositingFilter = "darkenBlendMode"
view.layer.addSublayer(overlayLayer1)
let overlayLayer2 = CALayer()
overlayLayer2.frame = CGRect(x: widthIncrement,
y: heightIncrement * 10,
width: widthIncrement * 5,
height: heightIncrement)
overlayLayer2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
overlayLayer2.compositingFilter = "divideBlendMode"
view.layer.addSublayer(overlayLayer2)
}
}
这是模拟器中的结果: