web-dev-qa-db-fra.com

Comment puis-je ajouter une ombre à un cercle UIImageView ou UIView?

J'essaie de créer un cercle UIImageView et cela fonctionne. Voici comment je le fais:

[self.pic.layer setMasksToBounds:YES];
[self.pic.layer setCornerRadius:50.0];

Je voudrais ajouter une ombre à la UIImageView. Le code ci-dessous ajoute une ombre à la vue de mon image. Toutefois, la vue de l'image redevient carrée. Quelqu'un peut-il me donner des indications pour résoudre ce problème? Ci-dessous, le code que j'utilise pour ajouter l'ombre:

self.pic.layer.shadowColor = [UIColor purpleColor].CGColor;
self.pic.layer.shadowOffset = CGSizeMake(0, 1);
self.pic.layer.shadowOpacity = 1;
self.pic.layer.shadowRadius = 1.0;
self.pic.clipsToBounds = NO;
16
Newbie

Utilisez la propriété CALayer 's shadowPath et ajoutez une UIBezierPath avec un rectangle arrondi

self.pic.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.pic.frame cornerRadius:50.0].CGPath;

EDIT

Pour une vue d'image carrée, cette technique ne fonctionne pas directement car, comme vous l'avez dit, la vue d'image revient à la place. Raison: vous définissez clipsToBounds = NO pour afficher l'ombre qui supprime l'écrêtage du rayon, où imageView est la sous-vue de container.

Solution de contournement:
Ajoutez votre imageview dans une vue conteneur, puis appliquez l’ombre du calque à ce conteneur. Voici le code que j'ai essayé.

[self.imageView.layer setCornerRadius:60.0];
[self.imageView.layer setMasksToBounds:YES];
self.imageView.clipsToBounds = YES;

self.container.backgroundColor = [UIColor clearColor];
self.container.layer.shadowColor = [UIColor blackColor].CGColor;
self.container.layer.shadowOffset = CGSizeMake(5,15);
self.container.layer.shadowOpacity = 0.5;
self.container.layer.shadowRadius = 2.0;
self.container.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.container.bounds cornerRadius:100.0].CGPath;

L'effet résultant est comme indiqué sur la capture d'écran,

enter image description here

J'espère que cela pourra aider!

43
Amar

Si quelqu'un cherche Swift 3 ou 4 qui fonctionne solution: 

    let imageSize: CGFloat = 64.0

    // Create a container which has a shadow
    let imageCotainer = UIView(frame: CGRect(x: 0, y: 0, width: imageSize, height: imageSize))
    imageCotainer.clipsToBounds = false
    imageCotainer.layer.shadowColor = UIColor.black.cgColor
    imageCotainer.layer.shadowOpacity = 0.2
    imageCotainer.layer.shadowOffset = CGSize(width: 0, height: 1)
    imageCotainer.layer.shadowRadius = 2

    // Create an image view that will be inserted into the container view
    let imageView = UIImageView(frame: imageCotainer.bounds)
    imageView.image = yourImage
    imageView.clipsToBounds = true
    let cornerRadius = imageView.frame.height / 2
    imageView.layer.cornerRadius = cornerRadius

    // Draw a shadow
    imageCotainer.layer.shadowPath = UIBezierPath(roundedRect: imageCotainer.bounds, cornerRadius: cornerRadius).cgPath
    // Add image into container
    imageCotainer.addSubview(imageView)

Parfois, vous devez également définir des contraintes pour l’image à l’intérieur du conteneur, mais cela peut également fonctionner sans elle dans certains cas. Mais si ce n'est pas le cas, ajoutez ceci:

    // Set constraints for the image inside the container view
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.topAnchor.constraint(equalTo: imageCotainer.topAnchor).isActive = true
    imageView.leftAnchor.constraint(equalTo: imageCotainer.leftAnchor).isActive = true
    imageView.rightAnchor.constraint(equalTo: imageCotainer.rightAnchor).isActive = true
    imageView.bottomAnchor.constraint(equalTo: imageCotainer.bottomAnchor).isActive = true
    imageView.heightAnchor.constraint(equalToConstant: imageSize).isActive = true
    imageView.widthAnchor.constraint(equalToConstant: imageSize).isActive = true
2
Tung Fam

Sans conteneur mais avec une vue de fond voici mes 2 centimes

Comme une extension Swift 2.2

    image?.applyCircleShadow(5, shadowOpacity: 1)
extension UIView {
    func applyCircleShadow(shadowRadius: CGFloat = 2,
                           shadowOpacity: Float = 0.3,
                           shadowColor: CGColor = UIColor.blackColor().CGColor,
                           shadowOffset: CGSize = CGSize.zero) {
        layer.cornerRadius = frame.size.height / 2
        layer.masksToBounds = false
        layer.shadowColor = shadowColor
        layer.shadowOffset = shadowOffset
        layer.shadowRadius = shadowRadius
        layer.shadowOpacity = shadowOpacity
    }
}
extension UIImageView {
    override func applyCircleShadow(shadowRadius: CGFloat = 2,
                                    shadowOpacity: Float = 0.3,
                                    shadowColor: CGColor = UIColor.blackColor().CGColor,
                                    shadowOffset: CGSize = CGSize.zero) {

        // Use UIImageView.hashvalue as background view tag (should be unique)
        let background: UIView = superview?.viewWithTag(hashValue) ?? UIView()
        background.frame = frame
        background.backgroundColor = backgroundColor
        background.tag = hashValue
        background.applyCircleShadow(shadowRadius, shadowOpacity: shadowOpacity, shadowColor: shadowColor, shadowOffset: shadowOffset)
        layer.cornerRadius = background.layer.cornerRadius
        layer.masksToBounds = true
        superview?.insertSubview(background, belowSubview: self)
    }
}
2
Arsonik

Je pourrais être un peu en retard.

Vous pouvez facilement définir les attributs requis sur l'inspecteur d'attributs de storyboard. 

 enter image description here

Le résultat serait quelque chose comme ça.

 Round Image

1
Sandeep Singh Rana

J'ai créé des classes personnalisées ( Swift 3 ou 4 ) et cela fonctionne très bien: 

class RoundShadowImageView: RoundView {

    var imageView = RoundImageView()

    var image: UIImage!  {
        didSet {
            imageView.image = image
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(imageView)
        needsUpdateConstraints()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        addSubview(imageView)
        needsUpdateConstraints()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        clipsToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOpacity = 0.1
        layer.shadowOffset = CGSize(width: 0, height: 10)
        layer.shadowRadius = 10
        layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: frame.height / 2.0).cgPath
    }

    override func updateConstraints() {
        super.updateConstraints()

        imageView.snp.makeConstraints { (make) -> Void in
            make.height.width.equalTo(self)
            make.center.equalTo(self)
        }
    }
}

class RoundImageView: UIImageView {

    override func layoutSubviews() {
        super.layoutSubviews()
        let radius: CGFloat = self.bounds.size.height / 2.0
        layer.cornerRadius = radius
        clipsToBounds = true
    }
}

class RoundView: UIView {

    override func layoutSubviews() {
        super.layoutSubviews()
        let radius: CGFloat = self.bounds.size.height / 2.0
        layer.cornerRadius = radius
        clipsToBounds = true
    }
}

Il y a 2 classes pour faire un conteneur et une image ronde. Et la classe principale qui combine les deux: celle que vous appelez.

0
Paul Bénéteau