web-dev-qa-db-ja.com

ContentInsetを使用したUICollectionViewがずっと下にスクロールしない

UICollectionViewのコンテンツインセットを設定しています:

[_collectionView setContentInset:UIEdgeInsetsMake(0.f, 0.f, 100.f, 0.f)];

次に、このメソッドを使用してUICollectionViewの一番下までプログラムでスクロールしています:

- (void)scrollToLastMessageAnimated:(BOOL)animated;
{
    if (_messages.count == 0) { return; }

    NSUInteger indexOfLastSection = _messagesBySections.count - 1;
    NSInteger indexOfMessageInLastSection = [_messagesBySections[indexOfLastSection] count] - 1;
    NSIndexPath *path = [NSIndexPath indexPathForItem:indexOfMessageInLastSection
                                            inSection:indexOfLastSection];

    [_collectionView scrollToItemAtIndexPath:path
                           atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                   animated:animated];
}

下にスクロールしていますが、contentInsetを無視しています。つまり、最後のセルは指定されたコンテンツインセットの下にあります。

enter image description here 左の画像は、ビューが表示された後にどのように表示されるかを示しています。右の画像では、最後のメッセージまで手動でさらにスクロールしました。

私はAutoLayoutを使用していますが、これが起こる理由はありますか?

編集:

IBセットアップのスクリーンショットは次のとおりです。 enter image description here

15
Ben Marten

今日、偶然に解決策を発見しました!

View Controllerを選択し、オプション「スクロールビューインセットを調整」のチェックを外します。

enter image description here

このオプションをオフにすると、iOSはビュー(およびおそらくそのサブビュー)のインセットを自動的に調整しません。

- (void)configureInsetsOfCollectionView
{
    [_collectionView setContentInset: UIEdgeInsetsMake(self.navigationController.navigationBar.bounds.size.height + [UIApplication sharedApplication].statusBarFrame.size.height + DEFAULT_SPACING, 0.f, _keyboardHeight + _toolbar.bounds.size.height + DEFAULT_SPACING, 0.f)];
    [_collectionView setScrollIndicatorInsets:UIEdgeInsetsMake(self.navigationController.navigationBar.bounds.size.height + [UIApplication sharedApplication].statusBarFrame.size.height, 0.f, _keyboardHeight + _toolbar.bounds.size.height, 0.f)];
}
34
Ben Marten

フローレイアウトを使用している場合は、_collectionView.collectionViewLayout.sectionInsetを設定してください。

9
Arjuna

スイフト版

collectionview.contentInset = UIEdgeInsetsMake(44,0,0,0)
collectionview.scrollIndicatorInsets = UIEdgeInsetsMake(44,0,0,0)
4
Yoni Katz

考えられる問題

CollectionViewをツールバーの下に設定し、両方のビューのスーパービューの下部に制約を追加しました。

解決

ツールバーの制約を下、先頭に設定し、幅と高さを固定サイズに設定します。 collectionViewの場合、制約を上部、ツールバーで下部に設定し、スーパービューおよび(代替)固定サイズの幅に設定します

更新

CollectionView

動作させるには、次の手順に従います。

コレクションビューを確認し、ツールバーの下に配置しないで、ドキュメントアウトラインでcollectionViewを選択してこれらの制約を追加し、ctrlをクリックしてビューにドラッグします。ポップアップが表示され、Shiftキーを押しながらこれらの制約を選択します。

CollectionView Constraints

ツールバー

ビュー内でctrlをドラッグして、先頭と末尾を確認します。そして、ツールバーの固定幅と高さを追加します。

Toolbar Constraints

ViewAppearsの前にスクロールを処理する

-(void)viewWillAppear:(BOOL)animated
{
    [collectionView reloadData];
    [self scrollToLastMessageAnimated:YES];
}
2
E-Riddie

ViewControllerクラスでreferenceSizeForFooterInSection関数を設定できます。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
    return CGSize(width: view.frame.width, height: 50)
}

高さを必要な値に設定するだけです。

1
T. Christiansen