1. ホーム
  2. iphone

[解決済み] targetContentOffsetForProposedContentOffset:withScrollingVelocity を UICollectionViewFlowLayout のサブクラス化せずに作成する。

2022-11-04 21:49:20

質問

私のアプリには非常にシンプルなcollectionViewがあります(正方形のサムネイル画像が一列に並んでいるだけです)。

私は、オフセットが常に左側に完全な画像を残すように、スクロールをインターセプトしたいと思います。 現時点では、どこまでもスクロールし、切り取られた画像を残します。

とにかく、私は関数を使用する必要があることを知っています。

- (CGPoint)targetContentOffsetForProposedContentOffset:withScrollingVelocity

を使うことができますが、私は標準的な UICollectionViewFlowLayout . サブクラス化してません。

をサブクラス化せずに、これを傍受する方法はないでしょうか? UICollectionViewFlowLayout ?

ありがとうございます。

どのように解決するのですか?

OK、答えはノーです。UICollectionViewFlowLayoutをサブクラス化しない限り、これを行う方法はありません。

しかし、それをサブクラス化することは、将来これを読んでいる人のために信じられないほど簡単です。

最初に私はサブクラスの呼び出しをセットアップしました MyCollectionViewFlowLayout を設定し、インターフェース・ビルダーでコレクション・ビュー・レイアウトをカスタムに変更し、フロー・レイアウト・サブクラスを選択しました。

この方法だと、IBでアイテムのサイズなどを指定できないので、MyCollectionViewFlowLayout.mで以下のようにしています...

- (void)awakeFromNib
{
    self.itemSize = CGSizeMake(75.0, 75.0);
    self.minimumInteritemSpacing = 10.0;
    self.minimumLineSpacing = 10.0;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
}

これは、私のためにすべてのサイズとスクロールの方向を設定します。

次に ...

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalOffset = proposedContentOffset.x + 5;

    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);

    NSArray *array = [super layoutAttributesForElementsInRect:targetRect];

    for (UICollectionViewLayoutAttributes *layoutAttributes in array) {
        CGFloat itemOffset = layoutAttributes.frame.origin.x;
        if (ABS(itemOffset - horizontalOffset) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemOffset - horizontalOffset;
        }
    }

    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}

これにより、左側の端に5.0のマージンをとってスクロールが終了するようになります。

必要なことはこれだけです。コードでフローレイアウトを設定する必要は全くありませんでした。