简体   繁体   English

如何圆化 UIView 的顶部两个角并在上方添加阴影?

[英]How to round top two corners of UIView and add shadow above?

I am trying to round the top two corners of a UIView and add a shadow above this view using a UIView extension.我正在尝试圆化 UIView 的顶部两个角,并使用 UIView 扩展名在此视图上方添加阴影。 However the solution I came up with isn't working.但是我想出的解决方案不起作用。 When I use the following solution the shadow only appears in the rounded corners and not above the view where I want it.当我使用以下解决方案时,阴影仅出现在圆角中,而不出现在我想要的视图上方。

extension UIView {
    
    func roundCornersWithShadow(_ corners: UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        layer.mask = mask
        mask.path = path.cgPath
        mask.shadowColor = UIColor.black.cgColor
        mask.shadowPath = mask.path
        mask.shadowOffset = CGSize(width: 0.0, height: -2.0)
        mask.shadowOpacity = 0.9
        mask.shadowRadius = 3
        layer.masksToBounds = false
    }
}

[SWIFT-5] iOS 11 introduced maskedCorners which results in smoother and better quality results. [SWIFT-5] iOS 11 引入了 maskedCorners,可产生更平滑、质量更好的结果。 You can still use the UIRectCorner in the function call and have it translated to CACornerMask:您仍然可以在 function 调用中使用 UIRectCorner 并将其转换为 CACornerMask:

extension UIView {

func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
    if #available(iOS 11.0, *) {
        clipsToBounds = true
        layer.cornerRadius = radius
        layer.maskedCorners = CACornerMask(rawValue: corners.rawValue)
    } else {
        let path = UIBezierPath(
            roundedRect: bounds, 
            byRoundingCorners: corners, 
            cornerRadii: CGSize(width: radius, height: radius)
        )
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}

} }

SWIFT 5: iOS 11 introduced maskedCorners which results in smoother and better quality results. SWIFT 5: iOS 11引入了maskedCorners ,可产生更平滑、质量更好的结果。 You can still use the UIRectCorner in the function call and have it translated to CACornerMask :您仍然可以在 function 调用中使用UIRectCorner并将其转换为CACornerMask

extension UIView {

    func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
        if #available(iOS 11.0, *) {
            clipsToBounds = true
            layer.cornerRadius = radius
            layer.maskedCorners = CACornerMask(rawValue: corners.rawValue)
        } else {
            let path = UIBezierPath(
                roundedRect: bounds, 
                byRoundingCorners: corners, 
                cornerRadii: CGSize(width: radius, height: radius)
            )
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            layer.mask = mask
        }
    }

    func addShadow(shadowColor: CGColor = UIColor.label.cgColor,
                   shadowOffset: CGSize = CGSize(width: 1.0, height: 2.0),
                   shadowOpacity: Float = 0.4,
                   shadowRadius: CGFloat = 3.0) {
        self.layer.shadowColor = shadowColor
        self.layer.shadowOffset = shadowOffset
        self.layer.shadowOpacity = shadowOpacity
        self.layer.shadowRadius = shadowRadius
        self.layer.masksToBounds = false
    }
}

These functions need to be applied in layoutSubviews() of your superview.这些功能需要在您的超级视图的 layoutSubviews() 中应用。

override func layoutSubviews() {
     roundCorners([.topLeft, .topRight], radius: 15)
     addShadow(shadowColor: UIColor.text1.cgColor, shadowOffset: CGSize(width: 0, height: -3), shadowOpacity: 0.2, shadowRadius: 5)
}
//must be used layoutSubviews inside . 
override func layoutSubviews() {
    super.layoutSubviews()
    backView.round(corners: [.topLeft,.topRight], radius: 40)
}

You can use this extension:您可以使用此扩展程序:

extension UIView {

    /// Rounds ``UIView`` corners.
    /// - Parameters:
    ///   - maskedCorners: Corners to be rounded.
    ///   - cornerRadius: Value to be set as corner radius.
    func roundCorners(maskedCorners: CACornerMask = [.layerMinXMinYCorner, .layerMaxXMinYCorner],
                      cornerRadius: CGFloat = roundedCornersRadius) {
        layer.cornerRadius = cornerRadius
        layer.maskedCorners = maskedCorners
        layer.masksToBounds = true
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM