【问题标题】:How can you mask a UIImage with a UIControl?如何用 UIControl 屏蔽 UIImage?
【发布时间】:2019-07-13 04:54:32
【问题描述】:

我可以将 UIImage 的 mask 属性设置为另一个 UIView,但是如果我将 UIImage 的 mask 属性设置为 UISwitch,则 UIImage 和 UISwitch 不会显示。

    recordMicSwitch = UISwitch()
    guard let sc = recordMicSwitch else { return }
    sc.frame = CGRect(x: deviceWidth - sc.frame.size.width - rightMargin, y: yPos, width: 0, height: 0)
    sc.onTintColor = UIColor(red: 0, green: 0.717, blue: 1.0, alpha: 1.0)
    view.addSubview(sc)

    let image: UIImage = UIImage(named: "testBGGradient.png")!
    let bgImage = UIImageView(image: image)
    bgImage.frame = CGRect(x:200, y:120, width:bgImage.frame.width/2, height:bgImage.frame.height/2)
    bgImage.mask = recordMicSwitch!
    self.view.addSubview(bgImage) 

【问题讨论】:

  • 请注意 - 如果我输入的每个字符都没有在我的计算机上显示旋转球,我就无法更新帖子。
  • sc.frame = CGRect(x: deviceWidth - sc.frame.size.width - rightMargin
  • 为什么将掩码设置为recordMicSwitch!,而不是sc
  • @ChewieTheChorkie - 你当然可以使用UISwitch之类的控件作为另一个视图的掩码,但是你做错了几件事(其中一个,你不能以这种方式更改交换机的框架)。然而,问题是,你真正想要做什么?您是否希望您的图像被开关的视觉外观所掩盖?或者您是否尝试使用图像将渐变应用到开关本身?
  • @ChewieTheChorkie - 好的,到目前为止,您尝试使用UISwitch 的“可见”部分作为图像视图的掩码......但您想要另一种方式-大约。我怀疑您是否可以在不使用自定义开关的情况下完成此操作。快速搜索custom uiswitch ...有很多选择。如果你找不到一款能满足你的需求,至少你会有一个好的起点。

标签: ios swift mask uiswitch uicontrol


【解决方案1】:

所以这实际上并不像将我们的图像屏蔽到UISwitch 那样简单。

这种简单方法行不通的原因是掩蔽实际上是如何工作的。当我们按照您的建议屏蔽图像时,我们会采用另一个视图的形状并将其应用于我们的图像。然后,我们的图像实际上被添加到父级。我们最终得到的是一个切割成我们的开关形状的图像(该图像不接收任何开关事件)。

我们实际上需要做的是更多的参与。我们需要将我们的图像添加到开关的subviews 的不同部分,并改为掩码。

为方便起见,我制作了一个自定义开关类,它在幕后完成繁重的工作:

class ImageTintSwitch: UISwitch {

    init(tintImage: UIImage) {
        super.init(frame: .zero)

        // Make sure we have subviews & grab the first one
        guard let element = subviews.first else { return }

        // Loop through only the subviews that clipToBounds inside the one we grabbed
        for (index, view) in element.subviews.enumerated() where view.clipsToBounds {

            // Add our image only where we need it
            configure(with: tintImage, on: element, maskedTo: view, atIndex: index)
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func configure(with image: UIImage, on parent: UIView, maskedTo view: UIView, atIndex index: Int) {
        // Make an imageView with our image
        let imageView: UIImageView = {
            let view = UIImageView(image: image)
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()

        // Insert our new imageView only where we need it
        parent.insertSubview(imageView, at: index)

        // Mask our imageView to the views that we found
        imageView.mask = view

        // Constrain our imageView to match the parent view
        NSLayoutConstraint.activate([
            imageView.centerXAnchor.constraint(equalTo: parent.centerXAnchor),
            imageView.centerYAnchor.constraint(equalTo: parent.centerYAnchor),
            imageView.widthAnchor.constraint(equalTo: parent.widthAnchor),
            imageView.heightAnchor.constraint(equalTo: parent.heightAnchor)
            ])
    }
}

要使用这个自定义开关,我们可以使用以下代码:

let customSwitch = ImageTintSwitch(tintImage: UIImage(named: "gradient.jpg") ?? UIImage())

结果如下:

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多