我试图用我称之为“BlurFilterMask”的图像覆盖图像。它是我用Swift Code动态添加的CALayer,这里是BlurFilterMask:
class BlurFilterMask : CALayer {
private let GRADIENT_WIDTH : CGFloat = 50.0
var origin : CGPoint = CGPointZero {
didSet {
setNeedsDisplay()
}
}
var diameter : CGFloat = 50.0 {
didSet {
setNeedsDisplay()
}
}
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func drawInContext(ctx: CGContext) {
CGContextSaveGState(ctx)
let clearRegionRadius : CGFloat = self.diameter * 0.5
let blurRegionRadius : CGFloat = clearRegionRadius + GRADIENT_WIDTH
let baseColorSpace = CGColorSpaceCreateDeviceRGB();
let colours : [CGFloat] = [0.0, 0.0, 0.0, 0.0, // Clear region
0.0, 0.0, 0.0, 0.6] // blur region color
let colourLocations : [CGFloat] = [0.0, 0.0]
let gradient = CGGradientCreateWithColorComponents (baseColorSpace, colours, colourLocations, 2)
CGContextDrawRadialGradient(ctx, gradient, self.origin, clearRegionRadius, self.origin, blurRegionRadius, .DrawsAfterEndLocation);
}
}
在我的UIViewController.viewDidLoad()
中,我调用addMaskOverlay(),这是实现:
func addMaskOverlay(){
let blurFilterMask = BlurFilterMask()
blurFilterMask.diameter = 80
blurFilterMask.frame = heroImageView.bounds
blurFilterMask.origin = heroImageView.center
blurFilterMask.shouldRasterize = true
heroImageView.layer.addSublayer(blurFilterMask)
blurFilterMask.setNeedsDisplay()
}
无论我运行什么模拟器,无论是iPhone 5还是iPhone 6或iPad 2,例如,我总是得到相同的中心,宽度和高度:
但我的BlurFilterMask的中心总是不同的,取决于设备模拟器,它永远不会在UIImageView的中心启动,例如在iPhone 5中:
这是iPhone 6:
我想也许我需要在我的CALayer BlurFilterMask上进行垂直居中和水平居中约束,所以我尝试添加约束:
heroImageView.layer.addSublayer(blurFilterMask)
let xConstraint = NSLayoutConstraint(item: blurFilterMask, attribute: .CenterX, relatedBy: .Equal, toItem: heroImageView, attribute: .CenterX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: blurFilterMask, attribute: .CenterY, relatedBy: .Equal, toItem: heroImageView, attribute: .CenterY, multiplier: 1, constant: 0)
heroImageView.addConstraint(xConstraint)
heroImageView.addConstraint(yConstraint)
但我不能将约束添加到CALayer我不认为,我尝试时出错:
由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'* + [NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]:约束项必须都是实例UIView或NSLayoutGuide。'**
似乎问题可能是约束,但如果我无法向CALayer添加约束......
该代码没有帮助......
不确定从何处开始,我们非常感谢任何建议。
答案 0 :(得分:4)
问题在于,当viewDidLoad
被调用时,布局还没有完成,所以你的测量是从视图控制器的初始状态获取的,很可能是故事板大小,如果这就是你正在使用的。
布局完成后,您需要致电blurFilterMask
并知道heroImageView
的最终尺寸。
您可以通过覆盖viewDidLayoutSubviews
来完成此操作,这是......
调用以通知视图控制器其视图刚刚布置了其子视图。
阅读the docs,因为有一些条件,但在你的情况下,这确实可以让你这么做..
class ViewController: UIViewController {
@IBOutlet var heroImageView: UIImageView!
var blurFilterMask:BlurFilterMask! = nil
func resetMaskOverlay(){
if blurFilterMask == nil {
blurFilterMask = BlurFilterMask()
blurFilterMask.diameter = 120
heroImageView.layer.addSublayer(blurFilterMask)
}
blurFilterMask.frame = heroImageView.bounds
blurFilterMask.origin = heroImageView.center
}
override func viewDidLayoutSubviews() {
resetMaskOverlay()
}
}
我在BlurFilterMask
CGContextTranslateCTM(ctx, 0.0, yDiff)*/
本来应该被评论出来,因为它没有多大意义离开......
class BlurFilterMask : CALayer {
let GRADIENT_WIDTH : CGFloat = 50.0
var origin : CGPoint = CGPointZero {
didSet {
setNeedsDisplay()
}
}
var diameter : CGFloat = 50.0 {
didSet {
setNeedsDisplay()
}
}
override func drawInContext(ctx: CGContext) {
CGContextSaveGState(ctx)
let clearRegionRadius : CGFloat = self.diameter * 0.5
let blurRegionRadius : CGFloat = clearRegionRadius + GRADIENT_WIDTH
let baseColorSpace = CGColorSpaceCreateDeviceRGB();
let colours : [CGFloat] = [0.0, 0.0, 0.0, 0.0, // Clear region
0.0, 0.0, 0.0, 0.6] // blur region color
let colourLocations : [CGFloat] = [0.0, 0.0]
let gradient = CGGradientCreateWithColorComponents (baseColorSpace, colours, colourLocations, 2)
CGContextDrawRadialGradient(ctx, gradient, self.origin, clearRegionRadius, self.origin, blurRegionRadius, .DrawsAfterEndLocation);
}
}