Swift - 在蒙版图像上放置阴影
Posted
技术标签:
【中文标题】Swift - 在蒙版图像上放置阴影【英文标题】:Swift - drop shadow on the masked image 【发布时间】:2021-09-15 13:54:13 【问题描述】:我只是想给图像添加一个阴影,而不仅仅是矩形,我想应用与图像相同的蒙版效果。 关于堆栈溢出,我发现了同样的问题,但答案是在 Objective-c 语言中提出的 - ios SDK - drop shadow on masked image 你能帮我解决这个问题的快速代码吗? 提前致谢。
class drawView: UIView
override func draw(_ rect: CGRect)
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else
return
self.drawCircle(context)
private func drawCircle(_ context: CGContext)
context.setStrokeColor(UIColor.black.cgColor)
let newMask = CAShapeLayer()
let circlePath = UIBezierPath(ovalIn: .init(x: 0, y: 0, width: 50, height: 50))
circlePath.stroke()
newMask.path = circlePath.cgPath
self.layer.mask = newMask //if I apply this, then shadow disappears
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOpacity = 0.15
self.layer.shadowOffset = .init(width: 10, height: -10)
self.layer.shadowRadius = 2
【问题讨论】:
添加有问题的代码@LeoDabus 【参考方案1】:有多种方法可以解决这个问题。
我建议使用带有UIImageView
子视图的自定义UIView
:
我们屏蔽imageView,然后将图层阴影应用到自定义视图本身:
class ShadowMaskImageView: UIView
let theImageView = UIImageView()
let maskShape = CAShapeLayer()
var image: UIImage = UIImage()
didSet
theImageView.image = image
override init(frame: CGRect)
super.init(frame: frame)
commonInit()
required init?(coder: NSCoder)
super.init(coder: coder)
commonInit()
func commonInit() -> Void
theImageView.translatesAutoresizingMaskIntoConstraints = false
addSubview(theImageView)
NSLayoutConstraint.activate([
theImageView.topAnchor.constraint(equalTo: topAnchor),
theImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
theImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
theImageView.bottomAnchor.constraint(equalTo: bottomAnchor),
])
theImageView.layer.mask = maskShape
layer.shadowOffset = CGSize(width: 10.0, height: -10.0)
layer.shadowColor = UIColor.black.cgColor
layer.shadowRadius = 2
layer.shadowOpacity = 0.15
override func layoutSubviews()
super.layoutSubviews()
maskShape.frame = bounds
// let's inset the image frame by 10-pts on all sides
// so our 10 x -10 shadow will fit inside the bounds
let r = bounds.insetBy(dx: 10.0, dy: 10.0)
// oval path
let pth = UIBezierPath(ovalIn: r)
maskShape.path = pth.cgPath
这是它的外观(红色轮廓矩形只是显示视图框架)...
首先,没有遮罩或阴影:
现在,只有面具:
并且,使用蒙版和阴影:
最后,没有显示框架的红色边框:
这是一个示例视图控制器:
class MaskShadowViewController: UIViewController
let testView = ShadowMaskImageView()
override func viewDidLoad()
super.viewDidLoad()
// make sure we can load the image
guard let img = UIImage(named: "sample") else
fatalError("Could not load sample image!!!")
// set the image
testView.image = img
// add testView and set its height equal to the ratio of the original image
testView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(testView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
testView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
testView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
testView.heightAnchor.constraint(equalTo: testView.widthAnchor, multiplier: img.size.height / img.size.width),
testView.centerYAnchor.constraint(equalTo: g.centerYAnchor),
])
// un-comment the following if we want to see the frame of our custom view
//let frameView = UIView()
//frameView.translatesAutoresizingMaskIntoConstraints = false
//view.addSubview(frameView)
//NSLayoutConstraint.activate([
// frameView.topAnchor.constraint(equalTo: testView.topAnchor, constant: 0.0),
// frameView.leadingAnchor.constraint(equalTo: testView.leadingAnchor, constant: 0.0),
// frameView.trailingAnchor.constraint(equalTo: testView.trailingAnchor, constant: 0.0),
// frameView.bottomAnchor.constraint(equalTo: testView.bottomAnchor, constant: 0.0),
//])
//
//frameView.layer.borderWidth = 1
//frameView.layer.borderColor = UIColor.red.cgColor
【讨论】:
以上是关于Swift - 在蒙版图像上放置阴影的主要内容,如果未能解决你的问题,请参考以下文章
java Android - Picasso的alpha / shadow变换(这允许您在源图像上绘制透明的黑色阴影)
java Android - Picasso的alpha / shadow变换(这允许您在源图像上绘制透明的黑色阴影)
java Android - Picasso的alpha / shadow变换(这允许您在源图像上绘制透明的黑色阴影)