Ios 阴影层中的快速切割孔

Ios 阴影层中的快速切割孔,ios,swift,swift3,calayer,shadow,Ios,Swift,Swift3,Calayer,Shadow,我想在UIView和Swift3 iOS的阴影层上切一个洞 我有一个容器UIView,它有两个子对象: 一个UIImageView 一个视图位于该图像覆盖的顶部 我想给叠加一个阴影,并剪切出该阴影的内部矩形,以便在ImageView的边缘创建类似辉光的效果 这是至关重要的辉光是插入,因为图像是采取屏幕宽度 到目前为止,我的代码是: let glowView = UIView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageHei

我想在UIView和Swift3 iOS的阴影层上切一个洞

我有一个容器UIView,它有两个子对象:

一个UIImageView 一个视图位于该图像覆盖的顶部 我想给叠加一个阴影,并剪切出该阴影的内部矩形,以便在ImageView的边缘创建类似辉光的效果 这是至关重要的辉光是插入,因为图像是采取屏幕宽度 到目前为止,我的代码是:

let glowView = UIView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight))
glowView.layer.shadowPath = UIBezierPath(roundedRect: container.bounds, cornerRadius: 4.0).cgPath
glowView.layer.shouldRasterize = true
glowView.layer.rasterizationScale = UIScreen.main.scale
glowView.layer.shadowOffset = CGSize(width: 1.0, height: 1.0)
glowView.layer.shadowOpacity = 0.4

container.addSubview(imageView)
container.addSubview(glowView)
现在的结果如下所示:

现在我想剪掉较暗的内部部分,以便只保留边缘的阴影
知道如何实现这一点吗?

尝试将此作为阴影路径:

let shadowWidth = 2.0 // Do this as wide as you want
var outterPath = UIBezierPath()
outterPath.move(to: CGPoint(x: shadowWidth, y: 0))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width, y: 0))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width, y: glowView.bounds.size.height))
outterPath.addLine(to: CGPoint(x: 0.0, y: glowView.bounds.size.height))
outterPath.addLine(to: CGPoint(x: 0.0, y: 0.0))
outterPath.addLine(to: CGPoint(x: shadowWidth, y: 0.0))
outterPath.addLine(to: CGPoint(x: shadowWidth, y: glowView.bounds.size.height - shadowWidth))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - shadowWidth, y: glowView.bounds.size.height - shadowWidth))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - shadowWidth, y: shadowWidth))
outterPath.addLine(to: CGPoint(x: shadowWidth, y: shadowWidth))
outterPath.close()
这不会创建一个圆角矩形,但对上面的代码稍作修改后,您也应该能够添加这些矩形。

多亏了我,我能够创建一个完全满足我需要的UIBezierPath 我在这里发布我的代码,以防以后有人遇到同样的问题

let innerRadius: CGFloat = 32.0 * UIScreen.main.scale
let shadowPath: UIBezierPath = UIBezierPath(roundedRect: self.view.bounds, cornerRadius: self.cornerRadius)
//shadowPath.append(UIBezierPath(roundedRect: self.view.bounds.insetBy(dx: 8, dy: 8), cornerRadius: self.cornerRadius))
let shadowWidth: CGFloat = 8.0 // Do this as wide as you want
var outterPath = UIBezierPath()
// Start at the top left corner with an x offset of the cornerRadius
outterPath.move(to: CGPoint(x: self.cornerRadius, y: 0))

// Draw a line to the top right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - self.cornerRadius, y: 0))
//Draw the round top right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - self.cornerRadius, y: self.cornerRadius), radius: self.cornerRadius, startAngle: (3 * CGFloat.pi) / 2, endAngle: 0, clockwise: true)

// Draw a line to the bottom right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width, y: glowView.bounds.size.height - self.cornerRadius))
// Draw the round bottom right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - self.cornerRadius, y: glowView.bounds.size.height -  self.cornerRadius), radius: self.cornerRadius, startAngle: 0, endAngle: CGFloat.pi / 2, clockwise: true)

// Draw a line to the bottom left corner
outterPath.addLine(to: CGPoint(x: self.cornerRadius, y: glowView.bounds.size.height))
// Draw the round bottom left corner
outterPath.addArc(withCenter: CGPoint(x: self.cornerRadius, y: glowView.bounds.size.height -  self.cornerRadius), radius: self.cornerRadius, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi, clockwise: true)

// Draw a line to the top left corner
outterPath.addLine(to: CGPoint(x: 0.0, y: self.cornerRadius))
// Draw the round top left corner
outterPath.addArc(withCenter: CGPoint(x: self.cornerRadius, y: self.cornerRadius), radius: self.cornerRadius, startAngle: CGFloat.pi, endAngle: (3 * CGFloat.pi) / 2, clockwise: true)

// Move to the inner start point and add the paths counterclockwise to prevent the filling of the inner area
outterPath.move(to: CGPoint(x: shadowWidth + innerRadius, y: shadowWidth))
// Draw the inner top left corner
outterPath.addArc(withCenter: CGPoint(x: shadowWidth + innerRadius, y: shadowWidth + innerRadius), radius: innerRadius, startAngle: (3 * CGFloat.pi) / 2, endAngle: CGFloat.pi, clockwise: false)

// Draw a line to the inner bottom left corner
outterPath.addLine(to: CGPoint(x: shadowWidth, y: glowView.bounds.size.height - innerRadius - shadowWidth))
// Draw the inner bottom left corner
outterPath.addArc(withCenter: CGPoint(x: shadowWidth + innerRadius, y: glowView.bounds.size.height - innerRadius - shadowWidth), radius: innerRadius, startAngle: CGFloat.pi, endAngle: CGFloat.pi / 2, clockwise: false)

// Draw a line to the inner bottom right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - innerRadius - shadowWidth, y: glowView.bounds.size.height - shadowWidth))
// Draw the inner bottom right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - innerRadius - shadowWidth, y: glowView.bounds.size.height - innerRadius - shadowWidth), radius: innerRadius, startAngle: CGFloat.pi / 2, endAngle: 0, clockwise: false)

// Draw a line to the inner top right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - shadowWidth, y: shadowWidth + innerRadius))
// Draw the inner top right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - innerRadius - shadowWidth, y: shadowWidth + innerRadius), radius: innerRadius, startAngle: 0, endAngle: (3 * CGFloat.pi) / 2, clockwise: false)

// Draw a line to the inner top left corner
outterPath.addLine(to: CGPoint(x: shadowWidth + innerRadius, y: shadowWidth))
outterPath.close()
幸运的是,现在很容易 现在做这件事很容易:

事情是这样的

import UIKit
class GlowBox: UIView {
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        backgroundColor = .clear
        layer.shadowOpacity = 1
        layer.shadowColor = UIColor.red.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowRadius = 3
        
        let p = UIBezierPath(
             roundedRect: bounds.insetBy(dx: 0, dy: 0),
             cornerRadius: 4)
        let hole = UIBezierPath(
             roundedRect: bounds.insetBy(dx: 2, dy: 2),
             cornerRadius: 3)
             .reversing()
        p.append(hole)
        layer.shadowPath = p.cgPath
    }
}
一个非常方便的提示: 当你添加它时,就是。像这样附加两个贝塞尔路径

第二个必须为正常或反向

请注意末尾附近的代码行:

             .reversing()
像大多数程序员一样,我永远记不起在不同的情况下是正常的还是相反的

简单的解决方案

很简单,两种都试试

只需尝试使用或不使用.reversing


它会以这样或那样的方式工作

在图像视图之前添加光晕视图。这应该很好用,我没有提到,但我不能这样做,因为图像占据了所有的宽度,需要对光晕进行调整inset@skaldesh,如果您仍在观看,则有一种更简单的方法来完成此操作!我回答了,谢谢,这对我来说是一个很好的基础!我会做一个答案,并参考你的答案!任何人在这里搜索,有一个非常简单的方法来做到这一点,还有正确的角落等,我键入了一个答案很酷的解决方案:谢谢@skaldesh-你摇滚。是的,幸运的是,这是这些天来变得非常容易的事情之一!干杯