UIImageView で cornerRadius と Shadow を同時に使いたい


UIImageView で角丸にしたい場合、これで実現できます。

let imageView = UIImageView()
imageView.layer.cornerRadius = 10
imageView.clipsToBounds = true

Shadow をつけるためにはこうですね、簡単です。

let imageView = UIImageView()
imageView.layer.cornerRadius = 10
imageView.layer.shadowColor = UIColor.black.cgColor
imageView.layer.shadowOffset = .zero
imageView.layer.shadowOpacity = 0.3
imageView.layer.shadowRadius = 4

しかし、 どちらもやろうとするとうまくいきません。

単純にどちらもやろうとしてみる

単純にどちらも合わせてみました。

let imageView = UIImageView()
imageView.layer.cornerRadius = 10
imageView.clipsToBounds = true
imageView.layer.shadowColor = UIColor.black.cgColor
imageView.layer.shadowOffset = .zero
imageView.layer.shadowOpacity = 0.3
imageView.layer.shadowRadius = 4

ただの角丸として表示されています

cornerRadius のためには clipsToBounds = true が必要なのですが、これは領域外の表示を切り捨てるオプションです。つまり Shadow も切り捨てられてしまうわけです。

clipsToBounds = false にしてみる

let imageView = UIImageView()
imageView.layer.cornerRadius = 10
imageView.clipsToBounds = false // デフォルトでも false
imageView.layer.shadowColor = UIColor.black.cgColor
imageView.layer.shadowOffset = .zero
imageView.layer.shadowOpacity = 0.3
imageView.layer.shadowRadius = 4

今度は cornerRadius が無効化されていまいました

shadow 専用 View を作る

月並みですが、 Shadow を表示するだけの UIView と UIImageView を別で作るようにしました。

let imageView = UIImageView()
albumImageView.layer.cornerRadius = 10
albumImageView.clipsToBounds = true

let shadowView = UIView()
shadowView.layer.cornerRadius = 10
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowOffset = .zero
shadowView.layer.shadowOpacity = 0.3
shadowView.layer.shadowRadius = 4

addSubView(shadowView)
addSubView(imageView)

うまく表示されました

他の方法

UIImageView だと clipsToBounds = true しないと角丸が無効化されましたが、 UIView では clipsToBounds = false でも角丸になるようです。

Bynomial Code » Fun with layers
UIView の backgroundColor に UIImage を指定して Radius, Shadow を実現するサンプルがあります。

個人的な意見ですが、 backgroundColor に画像をセットするよりは役割の違う View を2つ作った方がわかりやすい気がしました。