gpt4 book ai didi

ios - 添加一个以 UIImageView 为中心的 CALayer 子层

转载 作者:搜寻专家 更新时间:2023-10-30 22:13:59 26 4
gpt4 key购买 nike

  • Xcode 7.2
  • swift 2

我正在尝试用我称之为“BlurFilterMask”的图像覆盖图像。这是我用 Swift 代码动态添加的 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,我总是得到相同的中心、宽度和高度:

  • 打印(heroImageView.center) = (300.0, 67.5)
  • 打印(CGRectGetWidth(heroImageView.bounds)) = 600.0
  • print(CGRectGetHeight(heroImageView.bounds))//135.0

但是我的 BlurFilterMask 的中心总是在不同的地方,这取决于设备模拟器,它永远不会从 UIImageView 的中心开始,例如 iPhone 5:

enter image description here

这是 iPhone 6:

enter image description here

我想我的 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:]: Constraint items must each be an instance UIView 或 NSLayoutGuide。'**

似乎问题可能出在约束上,但如果我无法向 CALayer 添加约束...

该代码没有帮助...

不知道从这里去哪里,任何建议将不胜感激。

最佳答案

问题是,当 viewDidLoad 被调用时,布局尚未完成,因此您的测量值是从 View Controller 的初始状态获取的,如果您是这样的话,很可能是从 Storyboard大小获取的正在使用。

一旦布局完成并且 heroImageView 的最终大小已知,您需要调用 blurFilterMask

您可以通过重写 viewDidLayoutSubviews 来做到这一点...

Called to notify the view controller that its view has just laid out its subviews.

阅读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);

}

}

test1-5s test1-6s+

关于ios - 添加一个以 UIImageView 为中心的 CALayer 子层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35400789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com