何が起こっているのか
現在、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];
それでも同じ悲しい結果。
それで、何が機能しましたか?
1)サブクラスUICollectionViewFlowLayout
。
2)UICollectionView
のflowLayoutを新しいサブクラスに設定します。
3)UICollectionViewFlowLayout
サブクラスのinitメソッドで、目的の方向を設定します。
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
私の場合、それは水平です。
4)重要な部分:
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
現時点では、少し理論を立てるべきですが、正直なところ、私には手がかりがありません。
上記の回答は私にとってはうまくいきませんでしたが、画像をダウンロードした後、コードを置き換えました[self.myCollectionView reloadData]
with [self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
コレクションビューを更新すると、すべてのセルが表示されます。試してください。
誰からも提供された解決策はどれも、アプリに必要なカスタムレイアウトの助けにはなりませんでした。代わりに、私はこれをしなければなりませんでした:(そしてええ、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から4に変更しましたが、問題は二度と見られません。
同じ問題を突然実行し、スクロール中にセルが消える可能性のある理由の1つを理解するのに時間を費やしたので、答えも追加します。
UICollectionView
インスタンスがあります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
サイズを持ち、コンテンツサイズが対応する場合に正しいサイズスクロールするとすぐにoffsetY
がcontentSize
heightセルより大きくなりますすべて消えます。
解決策は、適切なUICollectionViewFlowLayout
サブクラス化です。 オーバーライドする必要があります であるすべてのメソッドをオーバーライドすると、すべて正常に機能します。
私の場合(最初のビューでセルが消える垂直スクロール)、推定サイズが正しくないためにセルが消えていました。 UICollectionView
は推定サイズを使用して、最初のビューで読み込むアイテムを計算しているようです。設定した推定サイズが大きすぎるため、最初の画面で読み込むアイテム数の計算が間違っていました。
推定高さを少し低くした瞬間、すべてのセルが正しく表示されました。
私にとって、この問題は、コンテンツの重複を防ぐために、コレクションビューを開いたキーボードに適応させる方法に関連しているように見えました。
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#ですが、他の人の助けになることを願っています。
これはUICollectionViewのバグではなく、おそらく- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
メソッドで正しいデータを返さないと思います。
このデモを見ることができます: https://github.com/lqcjdx/YLTagsChooser 、UICollectionViewを折りたたむときにすべてのセルを表示できます。
最近、消えているセルに遭遇し、「隠れた」セルをスキップするのではなく、誤って0x0サイズのセルを挿入していることがわかりました。結果として生じる振る舞いは非常に紛らわしく、これらの目に見えないセルが問題であることを示唆しませんでした。正しいサイズのセルとレイアウトが表示されますが、画面のオフ/オンをスクロールすると、いくつかの有効なセルが一貫して消えます。サイズが0のセルが混在するとこの動作が発生する理由はわかりませんが、それらを削除すると問題が解決しました。これはあなたの問題を引き起こしていないかもしれませんが、これは同様の症状を探している開発者に役立つかもしれません。