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]];
ただし、これによりドロップシャドウのみが生成されます。
これはバグですか、それとも何か問題がありますか?
私にとって素晴らしい作品:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
...
cell.layer.masksToBounds = YES;
cell.layer.cornerRadius = 6;
...
return cell;
}
すべてのサブビューを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;
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
私は同様の問題に遭遇したと思います。私の問題は、UICollectionViewCell
のサブビューでのクリッピングが、影と丸い境界線で適切に機能しないことでした。まったく同じコードは、私がUIView
にそのビュー(標準のUIScrollView
サブクラスとして)を持っていたときに、うまく機能しました。
要するに、私は-dequeueReusableCellWithReuseIdentifier:forIndexPath:
から取得した後、このセットアップをすべてinitWithCoder
から後の場所に移動しました。私のために問題を解決しました。 UICollectionViews
は、ある時点でセルのレイヤーに予期しないことをしているようですか?
トリッキーな瞬間があります。コーナーのカットと影のドロップは、1つのレイヤーで相互に排他的な機能です。影のドロップはフレーム拡張プロセスですが、コーナーは境界へのマスキングプロセスです。
解決策は機能分離です。セルレイヤーのシャドウを設定することをお勧めしますが、そのセルのcontentViewレイヤーの角を切り取ります。
サブクラスを使用してコレクションを作成する場合は、次のことを確認してください。
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];
魅力のように動作します。