2015-03-29 3 views
2

В следующем минимальном примере я создаю UICollectionView с пятью UICollectionViewCell с. Для каждого я создаю с тем же frame и установлю его свойство backgroundColor и добавьте его в качестве подслоя к UICollectionViewCell's layer. Ячейки, первоначально на экране, устанавливаются так, как ожидалось, но оставшиеся ячейки могут быть неправильного цвета и могут исчезать перед полностью выключенным экраном при прокрутке. Этот вопрос [1] предполагает, что это происходит потому, что ячейки первоначально не отображаются на экране (?), Но я не вижу ответов на них, как исправить проблему.Неожиданное поведение при добавлении подуровня в UICollectionViewCell

Ниже приведен минимальный рабочий пример. Несколько вещей, которые я пробовал, закомментированы:

  1. Установите цвет фона ячейки непосредственно, чтобы убедиться, что это не проблема с тем, как я настроил представление коллекции (это не так).
  2. Вызов setNeedsDisplay() (не действует).
  3. Удаление подслоев слоя ячейки (сбой при прокрутке).
import Foundation 
import UIKit 

enum Colors: Int { 
    case Red 
    case Orange 
    case Yellow 
    case Green 
    case Blue 
} 

class TestViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

    var collectionView = UICollectionView(frame: CGRect(x: 100, y: 100, width: 100, height: 100), collectionViewLayout: UICollectionViewFlowLayout()) 
    let reuseIdentifier = "ColorCell" 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.collectionView.dataSource = self 
     self.collectionView.delegate = self 
     self.collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "ColorCell") 
     self.view.addSubview(self.collectionView) 
    } 

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 5 
    } 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

     let cell: UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifier, forIndexPath: indexPath) as UICollectionViewCell 

     var l = CALayer() 
     l.frame = cell.frame 
     l.delegate = self 

     if let color = Colors(rawValue: indexPath.item) { 
      switch color { 
      case .Red: 
       l.backgroundColor = UIColor.redColor().CGColor 
//    cell.backgroundColor = UIColor.redColor() 
      case .Orange: 
       l.backgroundColor = UIColor.orangeColor().CGColor 
//    cell.backgroundColor = UIColor.orangeColor() 
      case .Yellow: 
       l.backgroundColor = UIColor.yellowColor().CGColor 
//    cell.backgroundColor = UIColor.yellowColor() 
      case .Green: 
       l.backgroundColor = UIColor.greenColor().CGColor 
//    cell.backgroundColor = UIColor.greenColor() 
      case .Blue: 
       l.backgroundColor = UIColor.blueColor().CGColor 
//    cell.backgroundColor = UIColor.blueColor() 
      } 
     } else { 
      l.backgroundColor = UIColor.blackColor().CGColor 
//   cell.backgroundColor = UIColor.redColor() 
     } 

//  for sub in cell.layer.sublayers { 
//   sub.removeFromSuperlayer() 
//  } 
     cell.layer.addSublayer(l) 
//  cell.setNeedsDisplay() 

     return cell 

    } 

} 

[1] CALayer delegate method drawLayer not getting called

ответ

1

Основная проблема заключается в том, что вы должны установить рамку слоя в пределах ор клетки, а не его рамки. Другая проблема заключается в том, что при повторной прокрутке и добавлении ячеек вы добавите дополнительные слои, так как вы добавляете подуровень при вызове cellForItemAtIndexPath. Чтобы устранить эти проблемы, я хотел бы создать подкласс UICollectionViewCell, а также добавлять и размер слоя там,

class CustomCollectionViewCell: UICollectionViewCell { 

    var l = CALayer() 

    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     l.frame = self.bounds 
     layer.addSublayer(l) 
    } 
} 

Затем cellForItemAtIndexPath становится

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifier, forIndexPath: indexPath) as CustomCollectionViewCell 

     cell.l.delegate = self 

     if let color = Colors(rawValue: indexPath.item) { 
      switch color { 
      case .Red: 
       cell.l.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5).CGColor 
      case .Orange: 
       cell.l.backgroundColor = UIColor.orangeColor().CGColor 
      case .Yellow: 
       cell.l.backgroundColor = UIColor.yellowColor().CGColor 
      case .Green: 
       cell.l.backgroundColor = UIColor.greenColor().CGColor 
      case .Blue: 
       cell.l.backgroundColor = UIColor.blueColor().CGColor 
      } 
     } else { 
      cell.l.backgroundColor = UIColor.blackColor().CGColor 
     } 
     return cell 
    } 

Если вы сделаете это, не забудьте зарегистрировать ваш пользовательский класс вместо UICollectionViewCell в viewDidLoad.

Смежные вопросы