J'essaie de créer un ImageView
qui a des coins arrondis et une ombre pour lui donner de la profondeur. J'ai pu créer une ombre pour le UIImageView
, mais chaque fois que j'ajoutais le code pour lui donner des coins arrondis, il n'y avait que des coins arrondis sans ombre. J'ai un IBOutlet
nommé myImage
, et il est à l'intérieur de la fonction viewDidLoad
. Quelqu'un at-il des idées sur la façon de le faire fonctionner? Qu'est-ce que je fais mal?
override func viewDidLoad() {
super.ViewDidLoad()
myImage.layer.shadowColor = UIColor.black.cgColor
myImage.layer.shadowOpacity = 1
myImage.layer.shadowOffset = CGSize.zero
myImage.layer.shadowRadius = 10
myImage.layer.shadowPath = UIBezierPath(rect: myImage.bounds).cgPath
myImage.layer.shouldRasterize = false
myImage.layer.cornerRadius = 10
myImage.clipsToBounds = true
}
Si vous définissez clipsToBounds
sur true
, cela arrondira les coins mais empêchera l'ombre d'apparaître. Pour résoudre ce problème, vous pouvez créer deux vues. La vue conteneur doit avoir l'ombre et sa sous-vue doit avoir les coins arrondis.
La vue du conteneur a clipsToBounds
définie sur false
et les propriétés d'ombre sont appliquées. Si vous souhaitez que l'ombre soit également arrondie, utilisez le constructeur UIBezierPath
qui prend un roundedRect
et cornerRadius
.
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
outerView.clipsToBounds = false
outerView.layer.shadowColor = UIColor.black.cgColor
outerView.layer.shadowOpacity = 1
outerView.layer.shadowOffset = CGSize.zero
outerView.layer.shadowRadius = 10
outerView.layer.shadowPath = UIBezierPath(roundedRect: outerView.bounds, cornerRadius: 10).cgPath
Ensuite, définissez la vue d'image (ou tout autre type de UIView
) pour qu'elle soit de la même taille que la vue du conteneur, définissez clipsToBounds
sur true
et donnez-lui un cornerRadius
.
let myImage = UIImageView(frame: outerView.bounds)
myImage.clipsToBounds = true
myImage.layer.cornerRadius = 10
Enfin, n'oubliez pas de faire de la vue d'image une sous-vue de la vue du conteneur.
outerView.addSubview(myImage)
Le résultat devrait ressembler à ceci:
Voici une autre solution (code testé) dans Swift 2.
Si vous définissez clipsToBounds sur true, cela arrondira les coins mais empêchera l'ombre d'apparaître. Vous pouvez donc ajouter la même taille UIView dans le storyboard derrière imageview et nous pouvons donner une ombre à cette vue
Swift 2.
outerView.layer.cornerRadius = 20.0
outerView.layer.shadowColor = UIColor.blackColor().CGColor
outerView.layer.shadowOffset = CGSizeMake(0, 2)
outerView.layer.shadowOpacity = 1
outerView.backgroundColor = UIColor.whiteColor()
Vous pouvez utiliser une classe simple que j'ai créée pour ajouter une image avec des coins arrondis et des ombres directement depuis Storyboard
Vous pouvez trouver la classe ici
Enfin, voici comment
C'est aussi simple que cela:
class ShadowRoundedImageView: UIView {
@IBInspectable var image: UIImage? = nil {
didSet {
imageLayer.contents = image?.cgImage
shadowLayer.shadowPath = (image == nil) ? nil : shapeAsPath }}
var imageLayer: CALayer = CALayer()
var shadowLayer: CALayer = CALayer()
var shape: UIBezierPath {
return UIBezierPath(roundedRect: bounds, cornerRadius:50) }
var shapeAsPath: CGPath {
return shape.cgPath }
var shapeAsMask: CAShapeLayer {
let s = CAShapeLayer()
s.path = shapeAsPath
return s }
override func layoutSubviews() {
super.layoutSubviews()
clipsToBounds = false
backgroundColor = .clear
self.layer.addSublayer(shadowLayer)
self.layer.addSublayer(imageLayer) // (in that order)
imageLayer.frame = bounds
imageLayer.contentsGravity = .resizeAspectFill // (as preferred)
imageLayer.mask = shapeAsMask
shadowLayer.shadowPath = (image == nil) ? nil : shapeAsPath
shadowLayer.shadowOpacity = 0.80 // etc ...
}
}
Voici la
UIImageView est inutile, vous utilisez un UIView
Vous avez besoin de deux couches, une pour l'ombre et une pour l'image
Pour arrondir un calque d'image, vous utilisez un masque
Pour arrondir un calque d'ombre, vous utilisez un chemin
Pour les qualités d'ombre, ajoutez évidemment du code comme bon vous semble
shadowLayer.shadowOffset = CGSize(width: 0, height: 20)
shadowLayer.shadowColor = UIColor.purple.cgColor
shadowLayer.shadowRadius = 5
shadowLayer.shadowOpacity = 0.80
Pour la forme réelle (le chemin bez), faites-en la forme que vous souhaitez.
(Par exemple, cette astuce https://stackoverflow.com/a/41553784/294884 montre comment ne faire qu'un ou deux coins arrondis.)
Sommaire
Faites votre bezier et ...