web-dev-qa-db-fra.com

UICollectionViewCell avec coins arrondis ET ombre portée ne fonctionne pas

Je veux que mes UICollectionViewCells aient des coins arrondis et des ombres portées mais j'ai rencontré un problème où il semble que je ne peux avoir que l'un ou l'autre, mais pas les deux.

Pour contourner les coins, j'utilise ce code dans l'initialisation de la cellule:

CALayer *layer = [self layer];
[layer setCornerRadius:4];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];

Pour ajouter simplement une ombre portée, j'utilise ce code dans l'initialisation de la cellule:

CALayer *layer = [self layer];
[layer setMasksToBounds:NO];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
[layer setShadowColor:[[UIColor blackColor] CGColor]];
[layer setShadowOffset:CGSizeMake(0.0f,0.5f)];
[layer setShadowRadius:8.0f];
[layer setShadowOpacity:0.2f];
[layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:layer.cornerRadius] CGPath]];

Pour essayer d'avoir des coins arrondis et une ombre portée j'utilise ce code dans l'initialisation de la cellule:

CALayer *layer = [self layer];
[layer setMasksToBounds:NO];
[layer setCornerRadius:4];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
[layer setShadowColor:[[UIColor blackColor] CGColor]];
[layer setShadowOffset:CGSizeMake(0.0f,0.5f)];
[layer setShadowRadius:8.0f];
[layer setShadowOpacity:0.2f];
[layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:layer.cornerRadius] CGPath]];

mais cela se traduit par l'ombre portée uniquement.

Est-ce un bug ou est-ce que je fais quelque chose de mal?

17
jj0b

Fonctionne très bien pour moi:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        ...
        cell.layer.masksToBounds = YES;
        cell.layer.cornerRadius = 6;
        ...
        return cell;
    }
31
Gennadiy Ryabkin

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 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 lightGrayColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 2.0f);
cell.layer.shadowRadius = 2.0f;
cell.layer.shadowOpacity = 1.0f;
cell.layer.masksToBounds = NO;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:cell.contentView.layer.cornerRadius].CGPath;

Swift 4.0

cell.contentView.layer.cornerRadius = 2.0
cell.contentView.layer.borderWidth = 1.0
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.masksToBounds = true
cell.layer.shadowColor = UIColor.lightGray.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
20
Lal Krishna

Je pense avoir rencontré un problème similaire. Mon problème était que l'écrêtage dans mes sous-vues du UICollectionViewCell ne fonctionnait pas correctement avec les ombres et les bordures arrondies. Le même code fonctionnait très bien avant quand j'avais cette vue (en tant que sous-classe UIView standard) dans un UIScrollView.

Donc, pour faire court, j'ai déplacé toute cette configuration de initWithCoder vers un endroit ultérieur après l'avoir obtenue de -dequeueReusableCellWithReuseIdentifier:forIndexPath:. Résolu le problème pour moi. On dirait que UICollectionViews fait quelque chose que je ne m'attendrais pas aux couches de leurs cellules à un moment donné?

2
Dennis

Il y a un moment délicat. Couper les coins et déposer l'ombre est une fonction mutuellement exclusive dans une seule couche. La suppression de l'ombre est un processus d'extension de cadre, mais les coins sont le processus de masquage aux limites.

La solution est en séparation de fonctions. Je recommande de configurer l'ombre pour le calque de cellule, mais de couper les coins pour le calque contentView de cette cellule.

2
Vov4yk

Si vous utilisez une sous-classe pour créer la collection, assurez-vous simplement de procéder comme suit.

CALayer *layer = [self layer];
[layer setCornerRadius:_cornerRadius];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
[layer setShadowColor:[[UIColor blackColor] CGColor]];
[layer setShadowOffset:CGSizeMake(0.0,4.0)];
[layer setShadowRadius:6.0f];
[layer setShadowOpacity:0.25];
[layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:layer.cornerRadius] CGPath]];

self.contentView.layer.cornerRadius = _cornerRadius;
self.contentView.layer.borderWidth= _borderWidth;
self.contentView.layer.borderColor = _borderColor.CGColor;
self.contentView.backgroundColor = [UIColor whiteColor];
self.backgroundColor = [UIColor clearColor];

fonctionne comme un charme.

0
Yung Dai