web-dev-qa-db-ja.com

角が丸く、ドロップシャドウが機能しないUICollectionViewCell

UICollectionViewCellsの角を丸め、シャドウをドロップしたいのですが、どちらか一方しか持てず、両方は持てないという問題が発生しました。

角を丸くするために、セルの初期化で次のコードを使用します。

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

ドロップシャドウを追加するには、セルの初期化で次のコードを使用します。

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]];

丸みを帯びた角とドロップシャドウを試してみるには、セルの初期化で次のコードを使用します。

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]];

ただし、これによりドロップシャドウのみが生成されます。

これはバグですか、それとも何か問題がありますか?

17
jj0b

私にとって素晴らしい作品:

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

すべてのサブビューをUICollectionViewCellコンテンツビューに配置すると、セルのレイヤーに影を設定し、contentViewのレイヤーに境界線を設定して、両方の結果を得ることができます。

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

私は同様の問題に遭遇したと思います。私の問題は、UICollectionViewCellのサブビューでのクリッピングが、影と丸い境界線で適切に機能しないことでした。まったく同じコードは、私がUIViewにそのビュー(標準のUIScrollViewサブクラスとして)を持っていたときに、うまく機能しました。

要するに、私は-dequeueReusableCellWithReuseIdentifier:forIndexPath:から取得した後、このセットアップをすべてinitWithCoderから後の場所に移動しました。私のために問題を解決しました。 UICollectionViewsは、ある時点でセルのレイヤーに予期しないことをしているようですか?

2
Dennis

トリッキーな瞬間があります。コーナーのカットと影のドロップは、1つのレイヤーで相互に排他的な機能です。影のドロップはフレーム拡張プロセスですが、コーナーは境界へのマスキングプロセスです。

解決策は機能分離です。セルレイヤーのシャドウを設定することをお勧めしますが、そのセルのcontentViewレイヤーの角を切り取ります。

2
Vov4yk

サブクラスを使用してコレクションを作成する場合は、次のことを確認してください。

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];

魅力のように動作します。

0
Yung Dai