【问题标题】:Gradient Layer over a CustomImageViewCustomImageView 上的渐变层
【发布时间】:2021-04-12 17:52:13
【问题描述】:

这是我第一次尝试将渐变层应用到 CustomImageView,为了在 UICollectionViewCell 中执行此操作,我决定创建以下函数:

func configureGradientOverlay() {
    
    let maskedView = UIView(frame: CGRect(x: 0, y: 0.5, width: 400, height: 400))
    maskedView.backgroundColor = .black

    let gradientMaskLayer = CAGradientLayer()
    gradientMaskLayer.frame = maskedView.bounds
    gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]
    gradientMaskLayer.locations = [0, 0.4, 0.6, 0.99]

    maskedView.layer.mask = gradientMaskLayer
    postImageView.addSubview(maskedView)   
}

这似乎可以在“postImageView”上应用渐变叠加,但正如您所见,我决定将“maskedView”的宽度和高度任意设置为 400。理想情况下,我'想将宽度和高度设置为'postImageView'的宽度和高度,但是当我尝试使用下面的代码执行此操作时,渐变叠加不再显示。

let postImageViewSize: CGRect = postImageView.bounds
let postImageViewWidth = postImageViewSize.width
let postImageViewHeight = postImageViewSize.height

let maskedView = UIView(frame: CGRect(x: 0, y: 0.5, width: postImageViewWidth, height: postImageViewHeight))

谁能告诉我我在这里做错了什么?

【问题讨论】:

  • 您从哪里调用此代码?如果 postimageview 没有完全初始化和显示,那么它的边界将不准确。您可以在最后的语句上放置一个断点并检查属性以查看它们是否符合您的预期。
  • 这个函数在init函数的addSubview(postImageView)之后被调用。难道是函数运行时 postImageView 没有完全初始化(即使它放在 addSubview(postImageView) 之后?
  • 在初始化中寻址边界总是有风险的,因为不能保证视图已经完成绘制。我会放弃我的方法(不确定它是否是最好的!0 到答案中。

标签: ios swift frontend cagradientlayer


【解决方案1】:

侧卫其实是对的。因此,继续将宽度和高度设置为“postImageView”的宽度和高度。

func configureGradientOverlay() {
    
    let postImageViewSize: CGRect = postImageView.bounds
    let postImageViewWidth = postImageViewSize.width
    let postImageViewHeight = postImageViewSize.height
  
    let maskedView = UIView(frame: CGRect(x: 0, y: 0.5, width: postImageViewWidth, height: postImageViewHeight))
    maskedView.backgroundColor = .black

    maskedView.layer.mask = gradientMaskLayer
    postImageView.addSubview(maskedView)
}

然后在layoutSublayers 中调用configureGradientOverlay

override func layoutSublayers(of layer: CALayer) {
    super.layoutSublayers(of: layer)
    
  let gradientMaskLayer = CAGradientLayer()
          gradientMaskLayer.frame = maskedView.bounds
          gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]
          gradientMaskLayer.locations = [0, 0.4, 0.6, 0.99]

          maskedView.layer.mask = gradientMaskLayer
}

瞧!

编辑(除了代码),postImageViewHeight 在此处将为零,除非您在 didLayoutSubviews() 中计算高度或其他内容。

【讨论】:

    【解决方案2】:

    在初始化程序中使用视图的 bounds 总是很幸运,因为无法保证在访问 bounds 属性时视图将被完全绘制。更好的方法是覆盖层的layoutSublayers(of:) 方法。

       override func layoutSublayers(of layer: CALayer) {
          super.layoutSublayers(of: layer)
          gradientMaskLayer.frame = self.bounds
       }
    

    假设您的图层是在视图中创建的,视图会自动将自己指定为图层的委托,从而提供layoutSublayers(of:) 方法,然后您可以按上述方式覆盖该方法。如果您不在视图中创建它,那么您必须自己设置委托功能。我建议在视图中进行:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多