如何在普通 UIView(不是 UIImage)上获得乘法混合模式

问题描述 投票:0回答:2

我的 iPad 应用程序中有一张图像,我基本上想在它上面放置一个滤色镜。为此,我有一个彩色 UIView,它被屏蔽为我放在图像上的特定形状。由于调整 Alpha 并没有给我带来想要的效果,我想改用混合模式。

据我所知,您只能在图像上使用混合模式,而不能在普通视图上使用。视图的颜色是动态的,所以我不能只使用图片来代替。

我也尝试将视图光栅化为图像,但这变得全是像素和奇怪的东西,但也许我做错了什么。

所以,基本问题是:是否可以将混合模式应用于视图?或者我应该采取完全不同的方法来达到相同的目标?

ios uiview filter uiimage blend
2个回答
16
投票

查看 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()

11
投票

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)
    }
}

这是模拟器中的结果:

© www.soinside.com 2019 - 2024. All rights reserved.