2013-07-17 40 views
14

イメージのグリッドを持つUICollectionViewがあります。 1つをタップすると、グリッドが開き、いくつかの詳細を含むサブビューが表示されます。このように:スクロール後にUICollectionViewが古いセルを削除しない

Supposed to look like this

私はUICollectionViewLayoutAttributesを調整すると、選択した項目の現在の行の下にあるすべてのセルのためのtransform3Dプロパティに変換を設定することによって、私のUICollectionViewLayoutでグリッドを開きます。これは本当にきれいに動作し、他のセルをグリッドに挿入する際の最初の試みよりもはるかに優れたアニメーションと簡単なアプローチです。

とにかく...ほとんどの場合は動作しますが、引き続き使用した後はコレクションビューで古い画像が表示されます。彼らはゴーストセルのようなものです。私はそれらをクリックすることはできません、彼らはコレクションビューから適切に削除されていない、彼らはタップを防止し、ちょうど迷惑である細胞の上に座っているようです。このように:

Problem looks like this

すべてのアイデアは、なぜこれらの細胞はこれをやっていますか?

編集: 私が追加したいのは、私がコレクションビューを本当に速くスクロールするときにのみ起こると思います。私は自分自身のUICollectionViewFlowLayout置換を書いて、それがまだ起こっているかどうかをテストします。します。

EDIT 2: 3D変換またはレイアウトはこれとは関係ありません。それはUICollectionViewのバグでなければなりません。私は本当に速くスクロールするだけで、停止して画面に表示されているビューを照会することで悪用することができます。多くの場合、セルの数が2倍になりますが、スタック上に重ねて表示されるので隠されています。上記の私の実装は私が行う翻訳のためにそれらを明らかにする。

これは実際にパフォーマンスを低下させる可能性があります。

ソリューションについては私の答えをご覧ください。

+0

あなたはスクリーンショットを投稿できますか? –

+0

奇妙なランダムな瞬間、数時間前にこれを見た。あなたのプロフィールページを見ました。アプリのアイデアがありました。 Flickr APIを検索しました。 GithubでFlickrKitを見た。名前を認識しました。笑! Netception! – Fogmeister

+0

ええ、私は周りに行く.....そしてあなたはリーズにいる、そして私はリーズ出身だ...実際には、そこを運転しようとしている。 – bandejapaisa

答えて

14

私の質問の詳細の2回目の編集はなぜこれが起こっているのか、そしてここに私の回避策です。それは弾丸の証拠はないが、それは私の場合で動作し、あなたがsomethign似たような経験場合は、私の解決策微調整することもできますbandejapaisa年代に

- (void) removeNaughtyLingeringCells { 

    // 1. Find the visible cells 
    NSArray *visibleCells = self.collectionView.visibleCells; 
    //NSLog(@"We have %i visible cells", visibleCells.count); 

    // 2. Find the visible rect of the collection view on screen now 
    CGRect visibleRect; 
    visibleRect.origin = self.collectionView.contentOffset; 
    visibleRect.size = self.collectionView.bounds.size; 
    //NSLog(@"Rect %@", NSStringFromCGRect(visibleRect)); 


    // 3. Find the subviews that shouldn't be there and remove them 
    //NSLog(@"We have %i subviews", self.collectionView.subviews.count); 
    for (UIView *aView in [self.collectionView subviews]) { 
     if ([aView isKindOfClass:UICollectionViewCell.class]) { 
      CGPoint origin = aView.frame.origin; 
      if(CGRectContainsPoint(visibleRect, origin)) { 
       if (![visibleCells containsObject:aView]) { 
        [aView removeFromSuperview]; 
       } 
      } 
     } 
    } 
    //NSLog(@"%i views shouldn't be there", viewsShouldntBeThere.count); 

    // 4. Refresh the collection view display 
    [self.collectionView setNeedsDisplay];  
} 

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 
    if (!decelerate) { 
     [self removeNaughtyLingeringCells]; 
    } 
} 

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    [self removeNaughtyLingeringCells]; 
} 
+1

ありがとうございました!私の場合、同じ状況で '隠された'セルを取り除くだけでうまくいきます。また、この問題を再現する私の方法です:1.非常に速くスクロールします。 2.減速が停止するのを待ちます。 3.セルを削除します。 4.アニメーションの削除が完了するのを待ちます。 –

2

迅速さらにコメントを:iOSの6の下でのみ、私はUICollectionViewにもアニメーションのトランジションをぶつける習慣があることを発見しました。オリジナルのセルは元の場所に残り、コピーが作成され、コピーがアニメ化されます。通常は原本の上にありますが、必ずしもそうではありません。したがって、単純な境界テストでは不十分でした。

私は、したがって、次んUICollectionViewのカスタムサブクラスを書いた:

- (void)didAddSubview:(UIView *)subview 
{ 
    [super didAddSubview:subview]; 

    // 
    // iOS 6 contains a bug whereby it fails to remove subviews, ever as far as I can make out. 
    // This is a workaround for that. So, if this is iOS 6... 
    // 
    if(![UIViewController instancesRespondToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) 
    { 
     // ... then we'll want to wait until visibleCells has definitely been updated ... 
     dispatch_async(dispatch_get_main_queue(), 
     ^{ 
      // ... then we'll manually remove anything that's a sub of UICollectionViewCell 
      // and isn't currently listed as a visible cell 
      NSArray *visibleCells = self.visibleCells; 
      for(UIView *view in self.subviews) 
      { 
       if([view isKindOfClass:[UICollectionViewCell class]] && ![visibleCells containsObject:view]) 
        [view removeFromSuperview]; 
      } 
     }); 
    } 
} 

は明らかにそれはテストもう少し直接的にはできません「このiOSの6」ではなく、それがオフ隠されていることは残念です私の実際のコードのカテゴリ。

bandejapaisaの答えの
+0

私はperformBatchUpdate:アニメーションを呼び出す速いスクロールの間にこの奇妙な "ゴースト"効果を見てきました。コレクションビューが現時点で画面上のセルに新しいセルを作成しているということは決して起こりませんでした。これは逆効果的なようです。良いキャッチ、ありがとう – SG1

0

AスウィフトUICollectionView拡張バージョン:

extension UICollectionView { 

    func removeNaughtyLingeringCells() { 

     // 1. Find the visible cells 
     let visibleCells = self.visibleCells() 
     //NSLog("We have %i visible cells", visibleCells.count) 


     // 2. Find the visible rect of the collection view on screen now 
     let visibleRect = CGRectOffset(bounds, contentOffset.x, contentOffset.y) 
     //NSLog("Rect %@", NSStringFromCGRect(visibleRect)) 


     // 3. Find the subviews that shouldn't be there and remove them 
     //NSLog("We have %i subviews", subviews.count) 
     for aView in subviews { 
      if let aCollectionViewCell = aView as? UICollectionViewCell { 

       let origin = aView.frame.origin 
       if (CGRectContainsPoint(visibleRect, origin)) { 
        if (!visibleCells.contains(aCollectionViewCell)) { 
         aView.removeFromSuperview() 
        } 
       } 

      } 
     } 

     // 4. Refresh the collection view display 
     setNeedsDisplay() 
    } 
} 
関連する問題