UIImageView 上的一致性居中 CALayer 子层 [英] Consistenlty Centering CALayer Sublayer over a UIImageView
问题描述
- Xcode 7.2
- 斯威夫特 2
我的问题是我无法始终将 CALayer 居中.
我有一个相关的 SO 问题
这是我的 print()
纵向模式旋转输出:
willTransitionToTraitCollection()!blurFilerMask != nilresetMaskOverlay()!(160.0, 128.0)328.0200.0BlurFilterMask ->drawInContext()!
但是 CALayer 在横向模式下居中:
这是我的 print()
横向模式旋转输出:
willTransitionToTraitCollection()!blurFilerMask != nilresetMaskOverlay()!(284.0, 108.0)568.0200.0BlurFilterMask ->drawInContext()!
我的 UIImage Size Inspector Screenshot,Constraints 最需要考虑的部分:
我的 UIImage 模式是 Scale To Fill
这是我的TestViewController
中的所有代码:
导入 UIKit类 TestViewController: UIViewController {@IBOutlet 弱 var heroImageView:UIImageView!var blurFilterMask:BlurFilterMask!= 零覆盖 func viewDidLoad() {super.viewDidLoad()//加载视图后进行任何其他设置.}覆盖 func viewDidLayoutSubviews() {super.viewWillLayoutSubviews()resetMaskOverlay()}覆盖 func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {super.willTransitionToTraitCollection(newCollection, withTransitionCoordinator: coordinator)打印(willTransitionToTraitCollection()!")如果 blurFilterMask != nil {打印(blurFilerMask != nil")blurFilterMask.removeFromSuperlayer()blurFilterMask = nil}}func resetMaskOverlay(){打印(resetMaskOverlay()!")打印(heroImageView.center)打印(CGRectGetWidth(heroImageView.bounds))打印(CGRectGetHeight(heroImageView.bounds))如果 blurFilterMask == nil {blurFilterMask = BlurFilterMask()}blurFilterMask.diameter = 80blurFilterMask.frame = heroImageView.boundsblurFilterMask.origin = heroImageView.centerblurFilterMask.shouldRasterize = trueheroImageView.layer.addSublayer(blurFilterMask)blurFilterMask.setNeedsDisplay()}}
这是我的 CALayer,我称之为 BlurFilterMask
:
导入 UIKit类 BlurFilterMask : CALayer {私人让 GRADIENT_WIDTH : CGFloat = 50.0变量原点:CGPoint = CGPointZero {已设置{//setNeedsDisplay()}}变量直径:CGFloat = 50.0 {已设置{//setNeedsDisplay()}}覆盖初始化(){超级初始化()}需要初始化?(编码器aDecoder:NSCoder){fatalError("init(coder:) 尚未实现")}覆盖 func drawInContext(ctx: CGContext) {print("BlurFilterMask -> drawInContext()!")CGContextSaveGState(ctx)让 clearRegionRadius : CGFloat = self.diameter * 0.5让 blurRegionRadius : CGFloat = clearRegionRadius + GRADIENT_WIDTH让 baseColorSpace = CGColorSpaceCreateDeviceRGB();let colours : [CGFloat] = [0.0, 0.0, 0.0, 0.0,//清除区域0.0, 0.0, 0.0, 0.6]//模糊区域颜色让 colourLocations : [CGFloat] = [0.0, 0.0]让梯度 = CGGradientCreateWithColorComponents (baseColorSpace, colours, colourLocations, 2)CGContextDrawRadialGradient(ctx,渐变,self.origin,clearRegionRadius,self.origin,blurRegionRadius,.DrawsAfterEndLocation);}}
现在进一步测试这个问题,我可以证明与我的第一个屏幕截图完全相反(第一个场景是:纵向模式未居中,而横向模式正确居中).
在下一个例子中.我已经更改了 UIImageView 约束,以便填充 UIImageView 填充 SuperView,您可以在下面看到我的 CALayer 在纵向模式下正确居中,但不是横向模式,这与我之前的屏幕截图演示完全相反:
UIImageView 约束:
带有 UIImageView填充"超视图约束的纵向模式:
具有 UIImageView填充"超视图约束的横向模式:
您的代码的问题是设置 BlurFilterMask 的中心.中心应该是 BlurFilterMask 的中心吧?使用这个更新的resetMaskOverlay"函数.
func resetMaskOverlay(){打印(resetMaskOverlay()!")打印(heroImageView.center)打印(CGRectGetWidth(heroImageView.bounds))打印(CGRectGetHeight(heroImageView.bounds))如果 blurFilterMask == nil {blurFilterMask = BlurFilterMask()}blurFilterMask.diameter = 80blurFilterMask.frame = heroImageView.boundsblurFilterMask.origin = CGPointMake(CGRectGetMidX(heroImageView.bounds), CGRectGetMidY(heroImageView.bounds))blurFilterMask.shouldRasterize = trueheroImageView.layer.addSublayer(blurFilterMask)blurFilterMask.setNeedsDisplay()}
- Xcode 7.2
- Swift 2
My issue is that I cannot consistently center my CALayer.
I have a related SO question here. The answer to this question was forward progress and brings me to the issue I am having now. Note in the answer to my related question, @WarrenBurton seems to only test portrait mode.
I think this issue, which really is calculating/positioning a sublayer dead center over a UIImageView may relate to the actual size of the Image selected for the UIImageView but I could be wrong about this.
Here is my print()
output for portrait mode rotation:
willTransitionToTraitCollection()!
blurFilerMask != nil
resetMaskOverlay()!
(160.0, 128.0)
328.0
200.0
BlurFilterMask -> drawInContext()!
But the CALayer is centered in Landscape mode:
Here is my print()
output for landscape mode rotation:
willTransitionToTraitCollection()!
blurFilerMask != nil
resetMaskOverlay()!
(284.0, 108.0)
568.0
200.0
BlurFilterMask -> drawInContext()!
My UIImage Size Inspector Screenshot, Constraints most important part to consider perhaps:
My UIImage mode is Scale To Fill
Here is all the code in my TestViewController
:
import UIKit
class TestViewController: UIViewController {
@IBOutlet weak var heroImageView: UIImageView!
var blurFilterMask:BlurFilterMask! = nil
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
super.viewWillLayoutSubviews()
resetMaskOverlay()
}
override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.willTransitionToTraitCollection(newCollection, withTransitionCoordinator: coordinator)
print("willTransitionToTraitCollection()!")
if blurFilterMask != nil {
print("blurFilerMask != nil")
blurFilterMask.removeFromSuperlayer()
blurFilterMask = nil
}
}
func resetMaskOverlay(){
print("resetMaskOverlay()!")
print(heroImageView.center)
print(CGRectGetWidth(heroImageView.bounds))
print(CGRectGetHeight(heroImageView.bounds))
if blurFilterMask == nil {
blurFilterMask = BlurFilterMask()
}
blurFilterMask.diameter = 80
blurFilterMask.frame = heroImageView.bounds
blurFilterMask.origin = heroImageView.center
blurFilterMask.shouldRasterize = true
heroImageView.layer.addSublayer(blurFilterMask)
blurFilterMask.setNeedsDisplay()
}
}
Here is my CALayer which I call BlurFilterMask
:
import UIKit
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) {
print("BlurFilterMask -> drawInContext()!")
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);
}
}
Now further testing of this issue, I can demonstrate the exact opposite of my first screenshots (the first scenario was: Portrait mode is NOT centered and Landscape mode is correctly centered).
In this next example. I have changed the UIImageView constraints so that fill the UIImageView fills the SuperView and you can see below my CALayer is correctly centered in Portrait mode but NOT Landscape mode, the exact opposite of my previous screenshot demo:
UIImageView Constraints:
Portrait mode with UIImageView "fill" superview constraints:
Landscape mode with UIImageView "fill" superview constraints:
Problem with your code is setting centre of your BlurFilterMask. Centre should centre of BlurFilterMask right? Use this updated 'resetMaskOverlay' function.
func resetMaskOverlay(){
print("resetMaskOverlay()!")
print(heroImageView.center)
print(CGRectGetWidth(heroImageView.bounds))
print(CGRectGetHeight(heroImageView.bounds))
if blurFilterMask == nil {
blurFilterMask = BlurFilterMask()
}
blurFilterMask.diameter = 80
blurFilterMask.frame = heroImageView.bounds
blurFilterMask.origin = CGPointMake(CGRectGetMidX(heroImageView.bounds), CGRectGetMidY(heroImageView.bounds))
blurFilterMask.shouldRasterize = true
heroImageView.layer.addSublayer(blurFilterMask)
blurFilterMask.setNeedsDisplay()
}
这篇关于UIImageView 上的一致性居中 CALayer 子层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!