1

私のNSCollectionViewが互いにNSCollectionアイテムを描画しています。 UPDATE:私は、サンプルプロジェクト GitHub Sample ProjectNSCollectionViewが互いにNSCollectionViewItemsを描画しています

UPDATEを追加しました:これは、やや When the app first launches it looks like this

UPDATE 私の現在の例が独自のnibファイルに現在ある2つのビューがあり変更されました専用のNScollectionViewItemオブジェクトでは、テストのために現在同じです。私は基本的にNSCollectionViewItemを持っています。これは子としてNSTextFieldを持つビューを持っています。すべての制約があります。

コレクションビューでは、グリッドコントローラとして設定されており、理想的には1つの列が必要です。

は、データとそれをロードするために、私は自分のViewController NSCollectionViewDataSource作られ、そして- (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath

更新されたコード 完全なコードが含ま実装:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Do any additional setup after loading the view. 

    [collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"]; 
    [collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"]; 

    cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy]; 
} 


- (void)setRepresentedObject:(id)representedObject { 
    [super setRepresentedObject:representedObject]; 

    // Update the view, if already loaded. 
} 

#pragma mark - NSCollectionViewDatasource - 
- (NSInteger)collectionView:(NSCollectionView *)collectionView 
numberOfItemsInSection:(NSInteger)section { 

    // We are going to fake it a little. Since there is only one section 
    NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]); 

    return [cellArray count]; 
} 

- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView 
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath { 

    NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]); 
    NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]); 

    NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath]; 

    return theItem; 
} 

UPDATE ItemOneをItemTwoクラスは両方とも空のクラスであり、それぞれのペン先はラベル付きのビューを持つNSCollectionViewItemを持っています。ビューはNSCollectionViewItemのビュープロパティによってNSCollectionViewItemに接続されています。

レイアウト:グリッド寸法:最大行数:0最大列:1分項目サイズ: 幅:250を次のように

NSCollectionViewグリッドが設定されているデフォルトのものを除いては制約がありません...高さ:150最大アイテムサイズ:幅:250高さ:150

これは、この時点でデータソースと結びついていない全体を設定するためのコードです。

設定を変更したり、フローにCollectionViewの種類を変更しても何も変更されていなくても同じように見えます。

私はAutoLayoutの問題として、元々いくつかの自動レイアウトの問題があったが、これらはすべて解決されていたため、この問題に近づいています。

ご協力いただければ幸いです。

+0

進歩しました!私はストーリーボードからNSCollectionViewItemsを削除し、そこにカスタムクラスのnibを入れました。私はクラスを登録し、識別子を含むように配列を変更しました。グリッドが1つの列に設定されていても、どちらのビューも2つの別々の列に読み込まれます。ビューをスクロールするとすぐに、2つのNSCollectionViewItemが再び1つになります。 – Tempus

+0

私はあなたのコードを試して、それは動作します。アイテムからすべての制約を削除するとどうなりますか?どのようにグリッドレイアウトを設定しましたか? – Willeke

+0

私はこれをすべて間違って考えていたようです。だから私はGitHub Repoで動作するバージョンを持っていますが、GridではなくFlowで動作し、Gridが動作することを期待していたことはありません。ビューサイズと同じ大きさのアイテムサイズを作成することで、単一の列を作成することができます。だからそれは働いているのです。しかし、私は異なる高さのビューを持つことができるかどうかを確認したい – Tempus

答えて

1

データ配列は、NSCollectionViewItemではなく、データを保持する必要があります。 collectionView:itemForRepresentedObjectAtIndexPath:ではmakeItemWithIdentifier:forIndexPath:に電話します。クラスまたはペン先を登録するには、registerClass:forItemWithIdentifier:またはregisterNib:forItemWithIdentifier:に電話してください。

さらに詳しい情報は、NSCollectionViewcollectionView:itemForRepresentedObjectAtIndexPath:およびmakeItemWithIdentifier:forIndexPath:です。

EDIT:

NSCollectionViewItemを提供するために、2つの方法があります。

registerClass:forItemWithIdentifier:。コレクションビューに新しい項目が必要な場合は、このクラスが作成されます。 NSCollectionViewItemNSViewControllerのサブクラスで、NSViewControllerはクラスと同じ名前のペン先を探します。 NSCollectionViewItemはペン先の所有者です。

registerNib:forItemWithIdentifier:。コレクションビューに新しい項目が必要な場合は、このnibをロードします。 NSCollectionViewItemはペン先のトップレベルオブジェクトです。

registerNib:forItemWithIdentifier:で使用するために、registerClass:forItemWithIdentifier:とxibを混ぜて使用しました。 registerNib:forItemWithIdentifier:を使用するか、xibを修正してください。

+0

コメントありがとうWilleke。私は同じ考えを持っていた。そこで、NSCollectionViewItemsが専用のクラスを持つ別々のnibファイルになるように変更しました。 View Controllerでは、識別子を登録し、配列を識別子の配列に変更します。'itemForRepresentedObjectAtIndex'私が' makeItemWithIdentifier'を実行し、アプリケーションが最初に読み込んだアイテムはすべて切り離されていますが、スクロールアクションを実行するとすぐに互いに結合されます。まだそれほどではありませんが、スクロールビューが成長していないようです。 – Tempus

+0

いいキャッチ!私がそれを働かせたにもかかわらず、Xibは間違っていました。そして今私はそれがいずれかの方法で使用できると思います。私はまだグリッドタイプを交換しました。フロータイプの追加された機能のために – Tempus

+0

あなたの提案でリポジトリを更新しました。そして、xibファイルを修正しました。 – Tempus

0

私はそれを理解しました。

と作業バージョンWorking Version of Collection View Sample Application

まず最初にgithubのレポを行いました。元のxibがセットアップされた方法のWillekeのキャッチのおかげで、私はGridタイプを動作させることができました。しかし、最終的には、Growビューは、セクションやビュー間の距離などをサポートしているので、必要なことをすることができれば、より良いタイプのビューです。グリッドタイプを使いたいと思っても、私のアプリのGrow型。

私はGrowタイプを使用して単一の列ビューを完成させました。成功のための

私の基準は以下のとおりです。

それは不均一なビューの高さをサポートできることを
  • は、単一の列があることを
  • 、および各カスタムビューが膨張する(各カスタムビューは、それが自分の高さだ持つことができます)ビューのサイズが拡大する場合

    @interface ViewController() 
    @property NSMutableArray *cellArray; 
    @property (weak) IBOutlet NSCollectionView *collectionView; 
    
    @end 
    
    @implementation ViewController 
    
    @synthesize cellArray; 
    @synthesize collectionView; 
    
    - (void)viewDidLoad { 
        [super viewDidLoad]; 
    
        // Do any additional setup after loading the view. 
    
        [collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"]; 
        [collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"]; 
    
        cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy]; 
    } 
    
    
    - (void)setRepresentedObject:(id)representedObject { 
        [super setRepresentedObject:representedObject]; 
    
        // Update the view, if already loaded. 
    } 
    
    #pragma mark - NSCollectionViewDatasource - 
    
    - (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView { 
        return 1; 
    } 
    
    - (NSInteger)collectionView:(NSCollectionView *)collectionView 
    numberOfItemsInSection:(NSInteger)section { 
    
        // We are going to fake it a little. Since there is only one section 
        NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]); 
    
        return [cellArray count]; 
    } 
    
    - (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView 
    itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath { 
    
        NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]); 
        NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]); 
    
        NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath]; 
    
        theItem.representedObject = [cellArray objectAtIndex:[indexPath item]]; 
    
        return theItem; 
    } 
    
    #pragma mark - NSCollectionViewDelegate - 
    - (NSSize)collectionView:(NSCollectionView *)collectionView 
           layout:(NSCollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 
        NSLog(@"%@", indexPath); 
    
        NSSize size = NSMakeSize(438, 150); 
        NSInteger width = 0; 
        NSInteger height = 0; 
        NSString *label = [cellArray objectAtIndex:[indexPath item]]; 
    
        NSRect collectionFrame = [collectionView frame]; 
    
        width = collectionFrame.size.width; 
    
        // TODO: This needs to be based on the actual value of the view instead of hardcoding a number in. 
        if ([label isEqualToString:@"Item1"]) { 
         height = 114; 
        } else if ([label isEqualToString:@"Item2"]) { 
         height = 84; 
        } 
    
        size = NSMakeSize(width, height); 
    
        return size;  
    } 
    
    @end 
    

    そしてそこにあなたがそれを持っている:ソースコード上へ、

。実装はそれほど悪くはありませんでした。 NSCollectionViewに表示される各カスタムビューは、NSCollectionViewItemと.xibファイルに定義されているため、簡単に変更できます。

脆弱な部分は、私が各ビューの高さを計算しているところです。サンプルアプリケーションでの実装で怠惰になっているため、脆いだけです。実際の実装では、実際のビューから動的に取得し、静的な数値に結び付けないようにします。

関連する問題