14

新しい UICollectionView と UICollectionViewLayout クラスをいじっています。カスタム レイアウトを作成し、UICollectionViewFlowLayout をサブクラス化しました。

セルのサイズが動的に変化しており、以下のデリゲート メソッドを使用してアイテムのサイズを設定しています

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout*)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

      NSLog(@"SETTING SIZE FOR ITEM AT INDEX %d", indexPath.row);
      return CGSizeMake(80, 80);
}

ここで、カスタム UICollectionViewFlowLayout クラスの prepareLayout メソッドの下で、これらのサイズ変数にアクセスして、配置方法を計算し、layoutAttributesForItemAtIndexPath 用にキャッシュできるようにする必要があります。

ただし、デリゲート メソッドで設定したカスタム アイテムのサイズに到達するために、UICollectionView または UICollectionViewFlowLayout の下にプロパティが見つからないようです。

4

6 に答える 6

13

自分で見つけました。

カスタムクラスライクを省略せずに実装UICollectionViewDelegateFlowLayout

@interface SECollectionViewCustomLayout : UICollectionViewFlowLayout 
                                          <UICollectionViewDelegateFlowLayout>

そして、あなたは呼び出すことができます

CGSize size = [self collectionView:self.collectionView 
                            layout:self 
            sizeForItemAtIndexPath:indexPath];
于 2012-09-25T15:50:45.550 に答える
8

迅速なバージョンがあります:

self.collectionView(self.collectionView, layout: self.collectionView.collectionViewLayout, sizeForItemAtIndexPath: indexPath)
于 2015-07-15T10:38:22.453 に答える
8

さまざまなUICollectionView...ヘッダー ファイルを確認し、WWDC 2012 セッション 219 - 高度なコレクション ビューとカスタム レイアウトの構築のビデオ (約 6:50 以降) を見ると、拡張可能なデリゲート パターンが動的型付けを利用して、レイアウトが適切にアクセスできるようになっているようです。その拡張デリゲート メソッド。


要するに...

  1. 独自のデリゲートを使用してカスタム レイアウトを定義する場合は、レイアウトのヘッダー ファイルでそのデリゲート プロトコルを定義します。
  2. デリゲート オブジェクト (通常はUI(Collection)ViewControllerコレクション ビューを管理する) は、このカスタム プロトコルをサポートするように自身を宣言する必要があります。
    • レイアウトが単なる 1UICollectionViewFlowLayoutつまたはそのサブクラスである場合、これは単に への適合を宣言することを意味しUICollectionViewDelegateFlowLayoutます。
    • デリゲートのインターフェイスにレイアウト ヘッダーを挿入し.mたくない場合は、ファイルのクラス拡張で自由にこれを行ってください。#import
  3. レイアウトからデリゲート メソッドにアクセスするには、コレクション ビューのデリゲートを呼び出します。
    • レイアウトのcollectionViewプロパティを使用し、必要なプロトコルに準拠するオブジェクトにデリゲートをキャストして、コンパイラを納得させます。
    • respondsToSelector:オプションのデリゲート メソッドを呼び出す前に、デリゲートが通常どおりであることを確認することを忘れないでください。実際、必要に応じて、すべてのメソッドに対してこれを実行しても害はありません。型キャストは、デリゲートが必要なメソッドを実装する実行時の保証がないことを意味するためです。


コードで...

そのため、一部の情報のデリゲートを必要とするカスタム レイアウトを実装する場合、ヘッダーは次のようになります。

@protocol CollectionViewDelegateCustomLayout <UICollectionViewDelegate>
- (BOOL)collectionView:(UICollectionView *)collectionView
                layout:(UICollectionViewLayout *)layout
shouldDoSomethingMindblowingAtIndexPath:(NSIndexPath *)indexPath;
@end

@interface CustomLayout : UICollectionViewLayout
// ...
@end


あなたのデリゲートは適合性を宣言します (私はここの実装ファイルでそうしました):

#import "CustomLayout.h"

@interface MyCollectionViewController () <CollectionViewDelegateCustomLayout>
@end

@implementation
// ...
- (BOOL)collectionView:(UICollectionView *)collectionView
                layout:(UICollectionViewLayout *)layout
shouldDoSomethingMindblowingAtIndexPath:(NSIndexPath *)indexPath
{
    return [self canDoSomethingMindblowing];
}
// ...
@end


レイアウトの実装では、次のようにメソッドにアクセスします。

BOOL blowMind;
if ([self.collectionView.delegate respondsToSelector:@selecor(collectionView:layout:shouldDoSomethingMindblowingAtIndexPath:)]) {
    blowMind = [(id<CollectionViewDelegateCustomLayout>)self.collectionView.delegate collectionView:self.collectionView
                                                                                             layout:self
                                                            shouldDoSomethingMindblowingAtIndexPath:indexPath];
} else {
    // Perhaps the layout also has a property for this, if the delegate
    // doesn't support dynamic layout properties...?
    // blowMind = self.blowMind;
}

とにかくデリゲートがそのメソッドに応答することを事前にチェックしているので、ここで型キャストしても安全であることに注意してください。


確たる証拠...

これは憶測にすぎませんが、Apple がUICollectionViewDelegateFlowLayoutプロトコルを管理する方法に問題があるのではないかと思います。

  • フロー レイアウトにはプロパティがないdelegateため、呼び出しはコレクション ビューのデリゲートを経由する必要があります。
  • UICollectionViewController拡張フロー レイアウト デリゲートに公に準拠していません (別のプライベート ヘッダーで準拠しているとは思えません)。
  • UICollectionViewdelegateプロパティは、「ベース」UICollectionViewDelegateプロトコルへの準拠のみを宣言します。UICollectionView繰り返しますが、型キャストの必要性を防ぐために、フロー レイアウトで使用されている のプライベート サブクラス/カテゴリがあるとは思えません。この点にさらに重みを加えるために、AppleUICollectionViewはドキュメントでサブクラス化をまったく推奨していません ( iOS 用コレクション ビュー プログラミング ガイド: カスタム レイアウトの作成)。

UICollectionView のサブクラス化は避けてください。コレクション ビューには、独自の外観がほとんどまたはまったくありません。代わりに、データ ソース オブジェクトからすべてのビューを取得し、レイアウト オブジェクトからすべてのレイアウト関連情報を取得します。

それでは、行きましょう。複雑ではありませんが、パラダイムに適した方法で行う方法を知っておく価値があります。

于 2014-02-06T07:41:29.970 に答える
4

GitHub でUICollectionView-FlowLayoutを確認してください。同じ考えです。これにより、flowLayout の拡張されたデリゲート メソッドへのアクセスが少しきれいになります。

于 2012-10-05T22:09:11.063 に答える
0

後の読者のために、IOS 7 にはそれを定義した UICollectionViewFlowLayout があります。

于 2015-04-25T05:25:01.707 に答える