我想在UI元素上应用CIFilter。我试图通过.filters成员将它应用到视图层。然而,过滤器不会被应用。
答案 0 :(得分:1)
以下是一种方法:使用UIGraphicsGetImageFromCurrentImageContext
生成UIImage
,将过滤器应用于该过滤器,并将包含过滤后图像的图像视图覆盖在原始组件上。
这是一种模糊(taken from my blog):
的方法获得UIView的模糊表示非常简单:我需要开始一个图像上下文,使用视图层的renderInContext方法渲染到上下文中,然后从上下文中获取UIImage:
UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
一旦我填充了图像,它就是一个相当标准的工作流程,可以应用高斯模糊:
guard let blur = CIFilter(name: "CIGaussianBlur") else
{
return
}
blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
blur.setValue(blurRadius, forKey: kCIInputRadiusKey)
let ciContext = CIContext(options: nil)
let result = blur.valueForKey(kCIOutputImageKey) as! CIImage!
let boundingRect = CGRect(x: -blurRadius * 4,
y: -blurRadius * 4,
width: frame.width + (blurRadius * 8),
height: frame.height + (blurRadius * 8))
let cgImage = ciContext.createCGImage(result, fromRect: boundingRect)
let filteredImage = UIImage(CGImage: cgImage)
模糊图像会比输入图像大,所以我需要明确createCGImage
中所需的尺寸。
下一步是在我的视图中添加UIImageView
并隐藏所有其他视图。我已将UIImageView
隐藏到BlurOverlay
,因此在删除它时,我可以确定我没有删除现有的UIImageView
:
let blurOverlay = BlurOverlay()
blurOverlay.frame = boundingRect
blurOverlay.image = filteredImage
subviews.forEach{ $0.hidden = true }
addSubview(blurOverlay)
说到去模糊,我想确保最后一个子视图是BlurOverlay
移除它之一并取消隐藏现有视图:
func unBlur()
{
if let blurOverlay = subviews.last as? BlurOverlay
{
blurOverlay.removeFromSuperview()
subviews.forEach{ $0.hidden = false }
}
}
最后,要了解UIView
目前是否模糊,我只需要查看其最后一个子视图是否为BlurOverlay
:
var isBlurred: Bool
{
return subviews.last is BlurOverlay
}