web-dev-qa-db-ja.com

UICollectionViewのセルが消える

何が起こっているのか

現在、UICollectionViews内で2つのUITableViewを使用するアプリケーションがあります。このようにして、Pulse Newsをアプリケーションのように作成します。これに関する私の問題は、6行目と11行目が完全に消えて、セルになるはずの場所に空白が残ることです。すべてのセルがこのようなものであったとしても、私は実際には気にしません(そして、このようにして、私は物事を正しく行っていなかったと推測できます)。

私の理論

6行目と11行目は、スクロールを開始したときに表示される行なので、デフォルトでは5つのセルが表示されます。

私が持っているもの

私が今していることはこれだけです:

 [self.collectionView registerNib:[UINib nibWithNibName:CELL_NIB_NAME bundle:nil] forCellWithReuseIdentifier:CELL_IDENTIFIER];

viewDidLoadで。セルの作成時:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CELL_IDENTIFIER forIndexPath:indexPath];

    NSMutableDictionary *dictionary = [self.DataSource objectAtIndex:[indexPath row]];

    [cell buildViewWithDictionary:dictionary withReferenceParent:self.referenceViewController];

    return cell;
}

だから、私の控えめな言い方をすれば、ここで何も変わっていません。私はデータソース(ダミーJSONファイル)に何か問題がありましたが、時には問題なく動作し、セルが表示されるので、その部分からは問題ないと思います。

だから私の「質問」:誰が何が起こっているのか知っていますか?これはiOSのバグだとは言いたくないのですが、他に何も考えられません。


編集1.

驚くべき部分は、この方法

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

[0,5]を計算せずにindexPath [0,4]から[0,6]になります。初めてiOSでこれが実際に発生するのを確認します。


編集2.

セルの作成方法を切り替えました。デキューする代わりに、古い方法を使用しています。

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CELL_NIB_NAME owner:self options:nil];
MyCell *cell = (MyCell *)[nib objectAtIndex:0];

それでも同じ悲しい結果。

52
Rui Peres

それで、何が機能しましたか?

1)サブクラスUICollectionViewFlowLayout

2)UICollectionViewのflowLayoutを新しいサブクラスに設定します。

3)UICollectionViewFlowLayoutサブクラスのinitメソッドで、目的の方向を設定します。

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

私の場合、それは水平です。

4)重要な部分

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
   return YES;
}

現時点では、少し理論を立てるべきですが、正直なところ、私には手がかりがありません。

34
Rui Peres

上記の回答は私にとってはうまくいきませんでしたが、画像をダウンロードした後、コードを置き換えました[self.myCollectionView reloadData] with [self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];コレクションビューを更新すると、すべてのセルが表示されます。試してください。

16
Yao Li

誰からも提供された解決策はどれも、アプリに必要なカスタムレイアウトの助けにはなりませんでした。代わりに、私はこれをしなければなりませんでした:(そしてええ、IT WORKS !!!)

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    CGSize size = [self collectionViewContentSize];
    rect.size.height = size.height*2;
    NSArray *atrributes_Super = [super layoutAttributesForElementsInRect:rect];
    return atrributes_Super;
}

結局のところ、UICollectionViewは画面の四角形に表示される要素の属性を探しているだけです。

6
CoderSaru

バグに関するロブのヒントは私を助けてくれました。バグでは、セクションのインセットとセルの幅と間隔が画面の幅と正確に一致すると、一部のセルの最初の列がランダムに消えて再表示されることがあります。サブクラスやセル幅を変更するのではなく、ストーリーボードの左右のセクションインセットを6から4に変更しましたが、問題は二度と見られません。

3
hoak

同じ問題を突然実行し、スクロール中にセルが消える可能性のある理由の1つを理解するのに時間を費やしたので、答えも追加します。

問題の前提条件:

  1. UICollectionViewインスタンスがあります
  2. UICollectionViewFlowLayoutSubclassがあります

問題

特定のポイントまでスクロールすると、セルがコレクションビューから消えます。

問題の原因は、UICollectionViewFlowLayoutのサブクラス化の誤りです。

documentation で明示的に述べたように:

すべてのレイアウトオブジェクトは、次のメソッドを実装する必要があります。

_- collectionViewContentSize
- layoutAttributesForElements(in:)
- layoutAttributesForItem(at:)
- layoutAttributesForSupplementaryView(ofKind:at:) // (if your layout supports -supplementary views)
-layoutAttributesForDecorationView(ofKind:at:) // (if your layout supports decoration views)
- shouldInvalidateLayout(forBoundsChange:)
_

上記のメソッドのUICollectionViewFlowLayout実装に依存することにより、func layoutAttributesForElements(in rect: CGRect)およびcollectionViewContentSizeが間違ったcontentSize(すべてのセルがitemSizeサイズを持ち、コンテンツサイズが対応する場合に正しいサイズスクロールするとすぐにoffsetYcontentSize heightセルより大きくなりますすべて消えます。

ソリューション

解決策は、適切なUICollectionViewFlowLayoutサブクラス化です。 オーバーライドする必要があります であるすべてのメソッドをオーバーライドすると、すべて正常に機能します。

2
fewlinesofcode

私の場合(最初のビューでセルが消える垂直スクロール)、推定サイズが正しくないためにセルが消えていました。 UICollectionViewは推定サイズを使用して、最初のビューで読み込むアイテムを計算しているようです。設定した推定サイズが大きすぎるため、最初の画面で読み込むアイテム数の計算が間違っていました。

推定高さを少し低くした瞬間、すべてのセルが正しく表示されました。

1
chandan thakur

私にとって、この問題は、コンテンツの重複を防ぐために、コレクションビューを開いたキーボードに適応させる方法に関連しているように見えました。

keyboardWillShowに応答するために私のオブザーバーで私はこれを持っていた:

var userInfo = obj.UserInfo[UIKeyboard.FrameEndUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    var windowOffset = this.Superview.ConvertPointToView(this.Frame.Location, UIApplication.SharedApplication.KeyWindow);
    var newHeight = rect.Y - windowOffset.Y;

    this._controller.CollectionView.Frame = new CGRect(0, 0, this._controller.CollectionView.Frame.Width, newHeight);
}

これに変更した後:

var userInfo = obj.UserInfo[UIKeyboard.FrameBeginUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    UIEdgeInsets contentInsets = new UIEdgeInsets(0, 0, rect.Height, 0);
    this._controller.CollectionView.ContentInset = contentInsets;
    this._controller.CollectionView.ScrollIndicatorInsets = contentInsets;
}

セル消失の問題は完全になくなりました。これはxamarinを使用したC#ですが、他の人の助けになることを願っています。

0
Dbl

これはUICollectionViewのバグではなく、おそらく- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rectメソッドで正しいデータを返さないと思います。

このデモを見ることができます: https://github.com/lqcjdx/YLTagsChooser 、UICollectionViewを折りたたむときにすべてのセルを表示できます。

0
lambert.lu

最近、消えているセルに遭遇し、「隠れた」セルをスキップするのではなく、誤って0x0サイズのセルを挿入していることがわかりました。結果として生じる振る舞いは非常に紛らわしく、これらの目に見えないセルが問題であることを示唆しませんでした。正しいサイズのセルとレイアウトが表示されますが、画面のオフ/オンをスクロールすると、いくつかの有効なセルが一貫して消えます。サイズが0のセルが混在するとこの動作が発生する理由はわかりませんが、それらを削除すると問題が解決しました。これはあなたの問題を引き起こしていないかもしれませんが、これは同様の症状を探している開発者に役立つかもしれません。

0
tyler