2015-09-05 139 views
1

使用UICollectionView我添加一個Label作爲一個subView與滾動方向設置爲水平單元格。在Label的內部,我添加了一個背景是圖像的按鈕。出於某種奇怪的原因,如果我向一個方向滾動視圖,然後回來,按鈕圖像似乎要麼遺留在按鈕的右側。不管是那個還是他們的另一個按鈕,都會在最初的按鈕下稍微向右移動。我意識到,我越玩越多的按鈕,他們轉移進一步權利。任何援助將不勝感激UICollectionView刷新問題

似乎問題不一樣,如果標籤是短

enter image description here

var padding = String(count: 2, repeatedValue: (" " as Character)) 

    let newLabel = UILabel(frame: CGRectZero) 
    newLabel.autoresizingMask = .FlexibleHeight 
    newLabel.backgroundColor = UIColor(red: 56/255, green: 143/255, blue: 212/255, alpha: 1) 
    newLabel.text = "\(padding)\(title)\(padding)" 
    newLabel.textColor = UIColor.whiteColor() 
    let fontName: CFStringRef = "Superclarendon-Regular" 
    newLabel.font = CTFontCreateWithName(fontName, 15, nil) 
    newLabel.adjustsFontSizeToFitWidth = true 
    newLabel.clipsToBounds = true 
    newLabel.layer.cornerRadius = 4 
    //Fit TO Text 
    newLabel.numberOfLines = 1 
    newLabel.sizeToFit() 
    //Add Button 
    if let image = UIImage(named: "Nav_Button_X"){//?//.CGImage 
     let button = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton 
     var imageWidth = image.size.width 
     var imageHeight = image.size.height 
     //Resize label for button 
     var oldLabelFrame = newLabel.frame 
     var buttonHeight = self.frame.height - self.sectionInsets.top - self.sectionInsets.bottom 
     var buttonWidth = newLabel.frame.width + imageWidth 
     //newLabel.frame = CGRect(x: oldLabelFrame.origin.x, y: oldLabelFrame.origin.y, width: oldLabelFrame.width, height: bh) 
     newLabel.frame.size = CGSize(width: buttonWidth, height: buttonHeight) 

     button.frame = CGRectMake(newLabel.frame.width - imageWidth, 0, imageWidth, newLabel.frame.height) 
     button.setBackgroundImage(image, forState: UIControlState.Normal) 
     newLabel.addSubview(button) 
    } 
    return newLabel 
} 

編輯發生:

我試圖重新創建僅使用視圖按鈕和NSMutableAttributedString的樣式,這可能或可能不是一個更好的解決方案聳聳肩,和問題persi所以它可能不是我如何構造按鈕的問題。有建議嗎?

我子類並設置UICollectionView像這樣

let flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout(); 
    flowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal 

    super.init(frame: CGRectMake(0, 0, width, height), collectionViewLayout: flowLayout); 

    self.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier); 

    self.autoresizingMask = UIViewAutoresizing.FlexibleWidth 
    self.backgroundColor = UIColor.whiteColor() 
    self.bounces = true 
    self.layer.cornerRadius = 5 
    self.scrollEnabled = true 
    self.delegate = self; 
    self.dataSource = self; 
    self.backgroundColor = UIColor.whiteColor(); 

FUNC的CollectionView(的CollectionView:UICollectionView,cellForItemAtIndexPath indexPath:NSIndexPath) - > UICollectionViewCell {

let cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell; 
cell.backgroundColor = UIColor.clearColor(); 
let cellItem = subCategories[indexPath.row] 
cell.contentView.addSubview(cellItem) 

// Configure the cell 
return cell 
} 

另一個有趣的特質是我從奇數編號的標籤中刪除了按鈕,並發現當我執行動作來解決問題時ns出現在所有標籤上

回答

2

這看起來像您的細胞正在被重複使用,並顯示來自舊細胞的視圖。

當您調用dequeueReusableCellWithReuseIdentifier時,該方法返回一個在UICollectionView中不再可見的單元格,但它不會清除它的內容。

假設您有可見的單元格A,B和C,您可以爲其中的所有元素添加子視圖(使用cell.contentView.addSubview(cellItem))。當你滾動直到單元格A不再可見,並且你調用dequeueReusableCellWithReuseIdentifier來獲得一個新的單元格(稱之爲D)時,你將重新使用單元格A,所以它會在你添加到單元格A之前添加子視圖,子視圖立即添加到細胞D.

擺脫這一點,你有兩個選擇:

  1. 如果您正在使用自定義UICollectionViewCell,你應該重寫prepareForReuse方法。你應該刪除所有的contentView的子視圖。
  2. 如果您使用的是UICollectionViewCell,你應該在調用cell.contentView.addSubview(cellItem)

之前,如果你想看看,如果你多次添加按鈕,再利用細胞刪除所有內容查看的子視圖,可以重現的問題,使用視圖層次檢查:

enter image description here

我創建了一個小項目來說明「髒」單元格的問題:https://github.com/lucaslt89/DirtyUICollectionViewCellsExample

0

就我而言,我在單元格的init方法中創建了視圖層次結構。

緩慢滾動時,單元格與多行標籤一起顯示完美。但是,當滾動速度過快時,標籤將具有重用單元格標籤的大小,因此顯得非常糟糕。

我正在設置preferredMaxLayoutWidth正確,但不過單元格在快速滾動時會有問題。

我的問題是通過調用解決setNeedsLayoutprepareForReuse

override func prepareForReuse() { 
    setNeedsLayout() 
    super.prepareForReuse() 
}