Donc, je suis déjà passé par divers articles sur l’ajout d’une 2e vue pour ajouter une ombre, mais je ne peux toujours pas le faire fonctionner si je veux l’ajouter dans UICollectionViewCell
. J'ai sous-classé UICollectionViewCell
, et voici mon code dans lequel j'ajoute divers éléments d'interface utilisateur à la vue du contenu de la cellule et ajoute une ombre au calque:
[self.contentView setBackgroundColor:[UIColor whiteColor]];
self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(0, 1);
self.layer.shadowRadius = 1.0;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = 0.5;
[self.layer setShadowPath:[[UIBezierPath bezierPathWithRect:self.bounds] CGPath]];
Je voudrais savoir comment ajouter un coin arrondi et une ombre à UICollectionViewCell
.
Aucune de ces solutions n'a fonctionné pour moi. Si vous placez toutes vos sous-vues dans la vue de contenu UICollectionViewCell, ce que vous êtes probablement, vous pouvez définir l'ombre sur le calque de la cellule et la bordure sur le calque de contentView pour obtenir les deux résultats.
cell.contentView.layer.cornerRadius = 2.0f;
cell.contentView.layer.borderWidth = 1.0f;
cell.contentView.layer.borderColor = [UIColor clearColor].CGColor;
cell.contentView.layer.masksToBounds = YES;
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 2.0f);
cell.layer.shadowRadius = 2.0f;
cell.layer.shadowOpacity = 0.5f;
cell.layer.masksToBounds = NO;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:cell.contentView.layer.cornerRadius].CGPath;
Swift 3.0
self.contentView.layer.cornerRadius = 2.0
self.contentView.layer.borderWidth = 1.0
self.contentView.layer.borderColor = UIColor.clear.cgColor
self.contentView.layer.masksToBounds = true
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 2.0)
self.layer.shadowRadius = 2.0
self.layer.shadowOpacity = 0.5
self.layer.masksToBounds = false
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.contentView.layer.cornerRadius).cgPath
Swift 3 version:
cell.contentView.layer.cornerRadius = 10
cell.contentView.layer.borderWidth = 1.0
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.masksToBounds = true
cell.layer.shadowColor = UIColor.gray.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 2.0)
cell.layer.shadowRadius = 2.0
cell.layer.shadowOpacity = 1.0
cell.layer.masksToBounds = false
cell.layer.shadowPath = UIBezierPath(roundedRect:cell.bounds, cornerRadius:cell.contentView.layer.cornerRadius).cgPath
Si cela peut aider: Voici le Swift pour arrondir les angles:
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true
avec cellule étant une variable contrôlant la cellule: vous utiliserez souvent ceci dans override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
Prendre plaisir!
Définissez les attributs layer
pour la cellule et non pas contentView
.
CALayer * layer = [cell layer];
[layer setShadowOffset:CGSizeMake(0, 2)];
[layer setShadowRadius:1.0];
[layer setShadowColor:[UIColor redColor].CGColor] ;
[layer setShadowOpacity:0.5];
[layer setShadowPath:[[UIBezierPath bezierPathWithRect:cell.bounds] CGPath]];
Voici la solution Swift 4, mise à jour pour arrondir les angles tous et pas uniquement les coins supérieurs:
contentView.layer.cornerRadius = 6.0
contentView.layer.borderWidth = 1.0
contentView.layer.borderColor = UIColor.clear.cgColor
contentView.layer.masksToBounds = true
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2.0)
layer.shadowRadius = 6.0
layer.shadowOpacity = 1.0
layer.masksToBounds = false
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: contentView.layer.cornerRadius).cgPath
layer.backgroundColor = UIColor.clear.cgColor
Vous devez simplement (a) définir cornerRadius
et (b) définir shadowPath
pour qu'il soit un rectangle arrondi ayant le même rayon que cornerRadius
:
self.layer.cornerRadius = 10;
self.layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius] CGPath];
Swift 4.2
Il faut ajouter ceci dans votre cellule personnalisée ou cellForItemAt: Si vous utilisez la méthode cellForItemAt: substitute self -> cell
self.layer.cornerRadius = 10
self.layer.borderWidth = 1.0
self.layer.borderColor = UIColor.lightGray.cgColor
self.layer.backgroundColor = UIColor.white.cgColor
self.layer.shadowColor = UIColor.gray.cgColor
self.layer.shadowOffset = CGSize(width: 2.0, height: 4.0)
self.layer.shadowRadius = 2.0
self.layer.shadowOpacity = 1.0
self.layer.masksToBounds = false
Cela vous donnera une cellule avec une bordure arrondie et une ombre portée.
J'ai dû faire de légers changements pour Swift:
cell.contentView.layer.cornerRadius = 2.0;
cell.contentView.layer.borderWidth = 1.0;
cell.contentView.layer.borderColor = UIColor.clearColor().CGColor;
cell.contentView.layer.masksToBounds = true;
cell.layer.shadowColor = UIColor.grayColor().CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 2.0);
cell.layer.shadowRadius = 2.0;
cell.layer.shadowOpacity = 1.0;
cell.layer.masksToBounds = false;
cell.layer.shadowPath = UIBezierPath(roundedRect:cell.bounds, cornerRadius:cell.contentView.layer.cornerRadius).CGPath;
Celui-ci a fonctionné pour moi
cell.contentView.layer.cornerRadius = 5.0
cell.contentView.layer.borderColor = UIColor.gray.withAlphaComponent(0.5).cgColor
cell.contentView.layer.borderWidth = 0.5
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: cell.contentView.frame.size.height - width, width: cell.contentView.frame.size.width, height: cell.contentView.frame.size.height)
border.borderWidth = width
cell.contentView.layer.addSublayer(border)
cell.contentView.layer.masksToBounds = true
cell.contentView.clipsToBounds = true
La réponse de Mike Sabatini fonctionne bien, si vous configurez les propriétés de la cellule directement sur la collectionView cellForItemAt, mais si vous essayez de les définir dans awakeFromNib () d'une sous-classe UICollectionViewCell personnalisée, vous vous retrouverez avec un mauvais jeu bezierPath sur les périphériques qui ne le sont pas. ne correspond pas à la largeur et à la hauteur précédemment définies dans votre Storyboard (IB).
La solution pour moi était de créer une fonction dans la sous-classe d’UICollectionViewCell et de l’appeler à partir de cellForItemAt comme suit:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? CustomCollectionViewCell{
cell.configure())
return cell
}
else {
return UICollectionViewCell()
}
}
Et sur le CustomCollectionViewCell.Swift:
class CustomCollectionViewCell: UICollectionViewCell{
func configure() {
contentView.layer.cornerRadius = 20
contentView.layer.borderWidth = 1.0
contentView.layer.borderColor = UIColor.clear.cgColor
contentView.layer.masksToBounds = true
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2.0)
layer.shadowRadius = 2.0
layer.shadowOpacity = 0.5
layer.masksToBounds = false
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: contentView.layer.cornerRadius).cgPath}
}
Vous pouvez définir la couleur de l'ombre, le rayon et le décalage dans UICollectionViewDataSource lors de la création d'une méthode ICollectionViewCell
cell.layer.shadowColor = UIColor.gray.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 2.0)
cell.layer.shadowRadius = 1.0
cell.layer.shadowOpacity = 0.5
cell.layer.masksToBounds = false
Voici mon point de vue sur la solution. Cela ressemble aux autres réponses, avec une différence essentielle. Cela ne crée pas de chemin qui dépend des limites de la vue. Chaque fois que vous créez un chemin basé sur les limites et le fournissez à la couche, vous pouvez rencontrer des problèmes lors de son redimensionnement et vous devez configurer des méthodes pour mettre à jour le chemin.
Une solution plus simple consiste à éviter d’utiliser tout élément dépendant des limites.
let radius: CGFloat = 10
self.contentView.layer.cornerRadius = radius
// Always mask the inside view
self.contentView.layer.masksToBounds = true
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 1.0)
self.layer.shadowRadius = 3.0
self.layer.shadowOpacity = 0.5
// Never mask the shadow as it falls outside the view
self.layer.masksToBounds = false
// Matching the contentView radius here will keep the shadow
// in sync with the contentView's rounded shape
self.layer.cornerRadius = radius
Maintenant, chaque fois que la taille des cellules change, l’API de la vue effectue tout le travail en interne.
Voici ma réponse, proche des autres, mais j'ajoute un rayon de coin au calque, sinon les coins ne se rempliront pas correctement. En outre, cela fait une jolie petite extension sur UICollectionViewCell
.
extension UICollectionViewCell {
func shadowDecorate() {
let radius: CGFloat = 10
contentView.layer.cornerRadius = radius
contentView.layer.borderWidth = 1
contentView.layer.borderColor = UIColor.clear.cgColor
contentView.layer.masksToBounds = true
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 1.0)
layer.shadowRadius = 2.0
layer.shadowOpacity = 0.5
layer.masksToBounds = false
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath
layer.cornerRadius = radius
}
}
Vous pouvez l'appeler dans collectionView(_:cellForItemAt:)
de la source de données une fois que vous avez retiré votre cellule de la file d'attente.
Si vous chargez la cellule à partir d'un xib, alors awakeFromNib est l'endroit où placer le code.
class MyCollectionViewCell: UICollectionViewCell {
override func awakeFromNib() {
layer.cornerRadius = 7
layer.masksToBounds = true
}
}