UICollectionViewCell'e yuvarlak köşe ve alt gölge ekleme


108

Bu yüzden, gölge eklemek için 2. görünüm eklemek için çeşitli gönderiler yaptım, ancak eklemek istersem hala çalışamıyorum UICollectionViewCell. Alt sınıfa ayırdım UICollectionViewCellve burada hücrenin içerik görünümüne çeşitli UI öğeleri eklediğim ve katmana gölge eklediğim kodum:

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

Yuvarlatılmış köşe ve gölgeyi nasıl ekleyeceğimi bilmek istiyorum UICollectionViewCell.


Başkaları tarafından anlamak için sorunuzu geliştirmeniz gerektiğini düşünüyorum. Sorduğunuz şey gerçekten dağınık
Dinesh Raja

tamam güncellendi, sadece UICollectionViewCell'e nasıl yuvarlak köşe ve gölge ekleyeceğimi öğrenmek istiyorum
Vincent Yiu

Hafifçe bir kenara - shadowRadius VEYA setShadowPath kullanın, bu bağlamda esasen aynı talimat olduğu için her ikisini de yapmanın bir anlamı yok (tüm yuvarlak köşeler). Daha karmaşık şekiller veya yuvarlatılmış köşelerin tüm köşelere uygulanmamasını istediğiniz yerlerde bir gölge yolu gereklidir.
Oliver Dungey

Yanıtlar:


196

Bu çözümlerin hiçbiri benim için işe yaramadı. Tüm alt görünümlerinizi muhtemelen olduğunuz UICollectionViewCell içerik görünümüne yerleştirirseniz, her iki sonucu da elde etmek için hücre katmanındaki gölgeyi ve contentView katmanındaki kenarlığı ayarlayabilirsiniz.

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

9
Bu benim için iyi çalıştıcell.layer.backgroundColor = [UIColor clearColor].CGColor;
2014

2
Bunun neden sadece üst köşelerimi yuvarladığına dair bir fikriniz var mı?
user3344977

@ user3344977 belki alt kırpılıyor? Köşeler yuvarlatılmış, ancak hücrenin görünen kısmının altında
CoderNinja

5
Bunun benim alt köşelerimi değil üst köşelerimi yuvarladığını görüyorum.
fatuhoku

2
Hücreleri seçerken / seçimini kaldırırken / taşıdığınızda köşelerin yuvarlak kalmasını nasıl sağlarsınız? Başlangıçta doğru şekilde çizdikten sonra hücreyi her nefes aldığımda köşelerim kare oluyor.
Adrian

33

Swift 3 versiyonu:

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

Her hücrenin sağ köşesine ve altına gölge efekti eklemem gerekiyor ve yukarıdaki kodun çalışma şekli, hücreyi gölgeli bir renkle dolduruyor ...
Joe Sene

25

Yardımcı olması durumunda: Köşeleri yuvarlamanın hızlı yolu:

cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true

hücreyi kontrol eden bir değişken olduğu için: bunu genellikle override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell

Zevk almak!


19

İşte Swift 4 çözümü, sadece üst köşeleri değil, her köşeyi yuvarlamak için güncelleniyor :

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

1
Swift 4,2 de çalışıyor, thanls
ShadeToD

3
Bir çözüm arıyordum ... teşekkürler genç Massimo: 'D
Massimo Polimeni

16

layerHücrenin niteliklerini ayarlayın , değil 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]];

3
Bu benim için işe yaramıyor gibi görünüyor. Benzer bir kod uitableviewcell için kullanıyorum ama bir koleksiyon görünüm hücresinde çalışmıyor gibi görünüyor. Aynı kodun cv hücresinde çalışmaması tuhaf.
Jason

Yukarıdaki yorumum için bir güncelleme. UICollectionViewCells'in UITableViewCells'den farklı bir gölge uzaklığı kullandığını buldum. Bir gölge görmüyorsanız, ofseti değiştirmeyi deneyin (Y değerini artırmak bana yardımcı oldu).
Jason

15

SWIFT 4.2

Bunu özel hücrenize veya cellForItemAt'a eklemelisiniz: CellForItemAt kullanıyorsanız: yaklaşma ikame self -> hücre

        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

Bu size yuvarlak kenarlı ve alt gölgeli bir hücre verecektir.


15

İşte cevabım, diğerlerine yakın, ancak katmana bir köşe yarıçapı ekliyorum, aksi takdirde köşeler doğru şekilde dolmayacaktır. Ayrıca bu, üzerinde güzel bir uzantı oluşturur 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
    }
}

collectionView(_:cellForItemAt:)Hücrenizin sırasını çıkardıktan sonra onu veri kaynağının içinde çağırabilirsiniz.


8

Aşağıdakilerle aynı yarıçapa sahip yuvarlatılmış bir rekt olarak (a) ayarlamanız cornerRadiusve (b) ayarlamanız yeterlidir :shadowPathcornerRadius

self.layer.cornerRadius = 10;
self.layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius] CGPath];

2
Bunun neden sadece alt köşelerimi yuvarladığını biliyor musunuz?
user3344977

Yuvarladığınız katman, bir şey tarafından kısmen gizlenmiş gibi görünüyor. Ayrıntılar olmadan bundan daha ileri gidemezsin.
Timothy Moose

Hey Tim, az önce bu soruyu sordum. Hızlıca elde edebileceğine dair bir his var. Sadece hücrenin altında / "altında" gölgem olduğu için mi? stackoverflow.com/q/27929735/3344977
user3344977

6

Swift için bazı ufak değişiklikler yapmak zorunda kaldım :

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;

4

Mike Sabatini'nin yanıtı iyi çalışıyor, hücre özelliklerini doğrudan collectionView cellForItemAt üzerinde yapılandırırsanız, ancak bunları özel bir UICollectionViewCell alt sınıfının awakeFromNib () 'sinde ayarlamaya çalışırsanız, yapmayan cihazlarda yanlış bir bezierPath ayarı ile sonlanırsınız. Storyboard'unuzda (IB) önceden ayarlanmış olan genişlik ve yükseklik ile eşleşmiyor.

Benim için çözüm, UICollectionViewCell alt sınıfı içinde bir işlev oluşturmak ve bunu cellForItemAt'dan çağırmaktı:

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()
    }
}

Ve CustomCollectionViewCell.swift üzerinde:

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}
 }

4

Bu tür bir etkiyi elde etmek için aşağıdaki yöntemi kullanıyorum:

extension UICollectionViewCell {
    /// Call this method from `prepareForReuse`, because the cell needs to be already rendered (and have a size) in order for this to work
    func shadowDecorate(radius: CGFloat = 8,
                        shadowColor: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3),
                        shadowOffset: CGSize = CGSize(width: 0, height: 1.0),
                        shadowRadius: CGFloat = 3,
                        shadowOpacity: Float = 1) {
        contentView.layer.cornerRadius = radius
        contentView.layer.borderWidth = 1
        contentView.layer.borderColor = UIColor.clear.cgColor
        contentView.layer.masksToBounds = true

        layer.shadowColor = shadowColor.cgColor
        layer.shadowOffset = shadowOffset
        layer.shadowRadius = shadowRadius
        layer.shadowOpacity = shadowOpacity
        layer.masksToBounds = false
        layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath
        layer.cornerRadius = radius
    }
}

3

Bu benim için çalıştı

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

2

Bir UICollectionViewCell oluştururken UICollectionViewDataSource yönteminde gölge rengini, yarıçapı ve uzaklığı ayarlayabilirsiniz

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

2

İşte çözümü benim görüşüm. Tek bir anahtar farkla diğer yanıtlara benzer. Görüntünün sınırlarına bağlı bir yol oluşturmaz. Sınırlara göre bir yol oluşturduğunuzda ve bunu katmana sağladığınızda, yeniden boyutlandırıldığında sorunlarla karşılaşabilirsiniz ve yolu güncellemek için yöntemler ayarlamanız gerekir.

Daha basit bir çözüm, sınırlara bağlı herhangi bir şeyi kullanmaktan kaçınmaktır.

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

Artık hücre boyutu değiştiğinde, görünüm API'si tüm işi dahili olarak yapacaktır.


Bence en temiz cevap. Yarıçapları senkronize tutma fikrini seviyorum.
Kirill Kudaev

2

Önemli bir şey buldum: UICollectionViewCell, clearyukarıda bunları çalıştırabilmek için backgroundColor rengine sahip olmalıdır .


Bu, gölgeyi kesmemek için ÇOK önemlidir! Bu cevabı görmezden gelme, ÇOK teşekkürler dostum!
DennyDog
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.