【问题标题】:Unable to get Layer mask of UIButton to work无法让 UIButton 的图层蒙版工作
【发布时间】:2016-06-16 16:01:16
【问题描述】:

我无法屏蔽 UIButton。它适用于 UIView,但不适用于 UIButton。

我的代码很简单:

let maskingLayer = CALayer()
maskingLayer.frame = backToLiveButton.bounds
let maskingImage = WxStyleKit.imageOfTimelineBackToLiveArrow(backToLiveButton.bounds)
maskingLayer.contents = maskingImage.CGImage
backToLiveButton.layer.mask = maskingLayer

你有什么想法吗?

谢谢

【问题讨论】:

  • WxStyleKit 是否来自paintcode?​​span>
  • 是的,WxStyleKit 来自paintcode
  • 能否把 StyleKit 相关部分的代码贴出来让我和其他人测试一下?
  • @Ike10 ny PaintCode 太大... :) 只需使用 UIImage(named: "maskingImage")" 加载图像
  • 按钮是完全可见还是完全隐藏?您的图片是否有纯色或透明背景?

标签: ios swift uibutton calayer


【解决方案1】:

我能够通过子类化UIButton 并覆盖drawRect 来使屏蔽起作用。有两个选项可以让它工作,要么将图像转换为 UIImage,要么修改 PaintCode 函数以返回 UIBezierPath 并使用 CAShapeLayer

选项 1:使用预定义图像

class MaskedButton: UIButton {

  @IBInspectable var imageString: String?

  override func draw(_ rect: CGRect) {
    super.draw(rect)
    if let imageString = imageString {
      let maskImage = UIImage(imageLiteralResourceName: imageString)
      let maskImageView = UIImageView(frame: rect)
      maskImageView.contentMode = .scaleAspectFit
      maskImageView.image = maskImage
      layer.mask = maskImageView.layer
    }
  }

}

在此方法中,imageString 属性在 Interface Builder 中设置,是 Assets.xcassets 中图像的名称。

选项 2:使用动态创建的 UIBezierPath

class MaskedButton: UIButton {

  override func draw(_ rect: CGRect) {
    super.draw(rect)
    let maskLayer = CAShapeLayer()
    maskLayer.path = Wx.drawCanvas1(frame: rect).cgPath
    layer.mask = maskLayer
  }

}

修改后的 PaintCode 函数

public class Wx : NSObject {

   //// Drawing Methods

   public class func drawCanvas1(frame: CGRect) -> UIBezierPath {

       //// Bezier Drawing
       let bezierPath = UIBezierPath()
       bezierPath.move(to: CGPoint(x: frame.minX + 8.88, y: frame.minY + 28.28))
       bezierPath.addCurve(to: CGPoint(x: frame.minX + 77.2, y: frame.minY + 1.57), controlPoint1: CGPoint(x: frame.minX + 32.99, y: frame.minY + 2.6), controlPoint2: CGPoint(x: frame.minX + 63.13, y: frame.minY - 4.59))
       ...
       bezierPath.close()

       return bezierPath
    }

}

此方法有效,但不幸的是,您必须为每种类型的按钮创建一个子类,因为它依赖于 drawRect 覆盖内的函数。我不知道有什么方法可以动态设置函数调用,但我希望这会有所帮助!

如果您有任何问题,请随时提问!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2013-02-10
    相关资源
    最近更新 更多