切換語言為:簡體

IOS開發中如何正確地給View設圓角和陰影效果

  • 爱糖宝
  • 2024-10-11
  • 2044
  • 0
  • 0

1.透過layer操作

iOS開發中,給 UIView 新增圓角通常是透過 layer.cornerRadius 來實現的。

myView.layer.cornerRadius = 10
myView.layer.masksToBounds = true

缺點:這種方式會觸發離屏渲染,影響效能。

因為 masksToBounds 是導致離屏渲染的一個重要原因,為避免,最好不要設定 masksToBounds 為 true。但是注意,只使用 cornerRadius ,只在不需要裁剪檢視內容時有效。

2.透過 UIBezierPath 繪製圓角

let r = 10  // 圓角半徑
let maskPath = UIBezierPath(roundedRect: myView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: r, height: r))
let maskLayer = CAShapeLayer()
maskLayer.frame = myView.bounds
maskLayer.path = maskPath.cgPath
myView.layer.mask = maskLayer

這種方式不會產生離屏渲染,但是,需要傳入View.bounds,如果你使用SnapKit進行佈局,bounds無法直接獲取到,只有在檢視佈局完成後才能正確獲取。所以,需要 重寫 layoutSubviews() 方法,確保在佈局完成後設定圓角。

class MyCustomView: UIView {
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 設定圓角
        // .....
    }
}

如果在 ViewController 中操作檢視,則在viewDidLayoutSubviews()中完成。

設定View的陰影效果

myView.layer.shadowColor = UIColor.black.cgColor
myView.layer.shadowOpacity = 0.5
myView.layer.shadowRadius = 4
myView.layer.shadowOffset = CGSize(width: 0, height: 2)

新增陰影效果,會觸發離屏渲染,因為陰影需要計算檢視的形狀,GPU 會進行復雜的計算。但是, 我們可以儘量設定 shadowPath,告訴系統陰影的形狀,這樣可以減少計算。新增程式碼:

myView.layer.shadowPath = UIBezierPath(rect: myView.bounds).cgPath

在同時使用圓角和陰影時,通常會產生離屏渲染。爲了避免這個問題,可以將陰影效果和圓角分開處理,通常透過新增一個單獨的 UIView 作為陰影層。

let shadowView = UIView(frame: myView.frame)
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowOpacity = 0.5
shadowView.layer.shadowOffset = CGSize(width: 0, height: 2)
shadowView.layer.shadowRadius = 10

shadowView.layer.cornerRadius = 10

shadowView.addSubview(myView)

補充:圖片設定圓角

// 使用 CoreGraphics 生成圓角圖片
func createRoundedImage(image: UIImage, cornerRadius: CGFloat) -> UIImage? {
    let rect = CGRect(origin: .zero, size: image.size)
    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
    UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
    image.draw(in: rect)
    let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return roundedImage
}

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.