有多种方法可以解决这个问题。
我建议使用带有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
}
}