給帶有圓角和方向向下三角形的 Label 設置陰影

概述

如題舶替,實現(xiàn)上述需求


image.png

思路

  1. 添加 contentView符隙,contentView 首先添加一個 shapeLayer
  2. 繼續(xù)向 contentView 添加一個 Label,Label.backgroundColor = .clear
  3. 在 contentView layoutSubviews() 中配置 shapeLayer崇棠,并且 shapeLayer 傳入的是 Label.bounds
override func layoutSubviews() {
        super.layoutSubviews()
        configShadowLayer()
}

其中, configShadowLayer() 主要是通過 UIBezierPath 繪制 Label 的形狀,并添加陰影

struct CornerRadii {
    let topLeft: CGFloat
    let topRight: CGFloat
    let bottomLeft: CGFloat
    let bottomRight: CGFloat

    init(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) {
        self.topLeft = topLeft
        self.topRight = topRight
        self.bottomLeft = bottomLeft
        self.bottomRight = bottomRight
    }
}
    private func CYPathCreateWIthRoundedRect(bounds: CGRect, cornerRadii: CornerRadii) -> UIBezierPath {
        let minX = bounds.minX
        let minY = bounds.minY
        let maxX = bounds.maxX
        let maxY = bounds.maxY

        let topLeftCenterX = minX + cornerRadii.topLeft
        let topLeftCenterY = minY + cornerRadii.topLeft

        let topRightCenterX = maxX - cornerRadii.topRight
        let topRightCenterY = minY + cornerRadii.topRight

        let bottomLeftCenterX = minX + cornerRadii.bottomLeft
        let bottomLeftCenterY = maxY - cornerRadii.bottomLeft

        let bottomRightCenterX = maxX - cornerRadii.bottomRight
        let bottomRightCenterY = maxY - cornerRadii.bottomRight

        let path = UIBezierPath.init()
        path.move(to: CGPoint(x: topLeftCenterX, y: minY))
        // 頂左
        path.addArc(withCenter: CGPoint(x: topLeftCenterX, y: topLeftCenterY), radius: cornerRadii.topLeft, startAngle: CGFloat.pi / 2 * 3, endAngle: CGFloat.pi, clockwise: false)
        path.addLine(to: CGPoint(x: minX, y: bottomLeftCenterY))
        // 底左
        path.addArc(withCenter: CGPoint(x: bottomLeftCenterX, y: bottomLeftCenterY), radius: cornerRadii.bottomLeft, startAngle: CGFloat.pi, endAngle: CGFloat.pi / 2, clockwise: false)
        // 畫三角形
        path.addLine(to: CGPoint(x: bottomLeftCenterX + 21, y: maxY))
        path.addLine(to: CGPoint(x: bottomLeftCenterX + 21 + 7, y: maxY + 6.2))
        path.addLine(to: CGPoint(x: bottomLeftCenterX + 21 + 14, y: maxY))

        path.addLine(to: CGPoint(x: bottomRightCenterX, y: maxY))
        // 底右
        path.addArc(withCenter: CGPoint(x: bottomRightCenterX, y: bottomRightCenterY), radius: cornerRadii.bottomRight, startAngle: CGFloat.pi / 2, endAngle: 0, clockwise: false)
        path.addLine(to: CGPoint(x: maxX, y: topRightCenterY))
        // 頂右
        path.addArc(withCenter: CGPoint(x: topRightCenterX, y: topRightCenterY), radius: cornerRadii.topRight, startAngle: 0, endAngle: CGFloat.pi / 2 * 3, clockwise: false)
        path.close()
        return path
    }

    func configShadowLayer() {
        let cornerRadii = CornerRadii(topLeft: 20, topRight: 20, bottomLeft: 20, bottomRight: 20)
        let path = CYPathCreateWIthRoundedRect(bounds: tipsLabel.bounds, cornerRadii: cornerRadii)
        shadowLayer.fillColor = UIColor.white.cgColor
        shadowLayer.path = path.cgPath
        shadowLayer.shadowPath = path.cgPath
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowColor = UIColor.gray.cgColor
        shadowLayer.shadowRadius =  6
        shadowLayer.shadowOffset = CGSize(width: 0, height: 2)
    }

注意:path.addArc(withCenter: CGPoint(x: topLeftCenterX, y: topLeftCenterY), radius: cornerRadii.topLeft, startAngle: CGFloat.pi / 2 * 3, endAngle: CGFloat.pi, clockwise: false) 中 圓角的startAngle 與 endAngle 均為順時針角度坝辫,具體如圖

圖一

拓展

1. 有圓角的UIView 添加陰影

思路:

  1. view.backgroundColor = .clear
  2. 按照上文思路,設置 CAShapeLayer射亏,作為 shadowLayer近忙,然后layer.addSublayer(shadowLayer),如果所有的圓角半徑都一樣的話智润,可以使用如下方法更簡單一些
    let berPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.topRight , .topLeft, .bottomLeft, .bottomRight], cornerRadii: CGSize(width: 8, height: 8))
    
  3. 添加一個 containerView, 其它所有的控件添加到這個 containerView 上及舍,同時設置 containerView.layer.maskToBounds = true, 以及 borderColor窟绷、borderWidth 等
  4. 如果使用 SnapKit, 需要override func layoutSubviews()锯玛,在 layoutSubviews() 方法中調用 生成 shadowLayer 的方法,或者在確定當前 view 尺寸以后再調用也可以兼蜈。
2. 繪制分別有不同的圓角的 UIView

也可以通過上述方法繪制 UIView 四個角分別有不同的圓角攘残,原理與設置圓角的幾種方式類似

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市为狸,隨后出現(xiàn)的幾起案子歼郭,更是在濱河造成了極大的恐慌,老刑警劉巖辐棒,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件病曾,死亡現(xiàn)場離奇詭異,居然都是意外死亡漾根,警方通過查閱死者的電腦和手機泰涂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來立叛,“玉大人负敏,你說我怎么就攤上這事∶厣撸” “怎么了其做?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵顶考,是天一觀的道長。 經常有香客問我妖泄,道長驹沿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任蹈胡,我火速辦了婚禮渊季,結果婚禮上,老公的妹妹穿的比我還像新娘罚渐。我一直安慰自己却汉,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布荷并。 她就那樣靜靜地躺著合砂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪源织。 梳的紋絲不亂的頭發(fā)上翩伪,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音谈息,去河邊找鬼缘屹。 笑死,一個胖子當著我的面吹牛侠仇,可吹牛的內容都是我干的轻姿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼逻炊,長吁一口氣:“原來是場噩夢啊……” “哼踢代!你這毒婦竟也來了?” 一聲冷哼從身側響起嗅骄,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤胳挎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后溺森,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慕爬,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年屏积,在試婚紗的時候發(fā)現(xiàn)自己被綠了医窿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡炊林,死狀恐怖姥卢,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤独榴,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布僧叉,位于F島的核電站,受9級特大地震影響棺榔,放射性物質發(fā)生泄漏瓶堕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一症歇、第九天 我趴在偏房一處隱蔽的房頂上張望郎笆。 院中可真熱鬧,春花似錦忘晤、人聲如沸宛蚓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苍息。三九已至,卻和暖如春壹置,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背表谊。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工钞护, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爆办。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓难咕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親距辆。 傳聞我的和親對象是個殘疾皇子余佃,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344