70

UIScrollViewアイコンのグリッドをレイアウトする があります。iOS Springboard のレイアウトを想像すると、ほとんど正解に近くなります。横方向のページ スクロールがあります (Springboard と同様)。ただし、レイアウトが正しくないようです。アイテムを上から下に並べているように見えます。その結果、表示するアイテムの数が多いため、最後の列には 2 行しかありません。Springboard に表示されるように、最後のページの最後の行に 2 つの項目を配置したいと思います。

UICollectionViewこれは、およびその関連クラスでどのように達成できますか? カスタムを書く必要がありますUICollectionViewFlowLayoutか?

4

12 に答える 12

101

UICollectionViewFlowLayout のスクロール方向を水平に設定してみましたか?

[yourFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

また、スプリングボードのようにページングしたい場合は、次のようにコレクション ビューでページングを有効にする必要があります。

[yourCollectionView setPagingEnabled:YES];
于 2013-10-18T15:42:22.233 に答える
79

最初のアプローチ

UIPageViewControllerの配列で使用するのはUICollectionViewControllersどうですか?各 で適切な数のアイテムを取得UICollectionViewControllerする必要がありますが、難しいことではありません。Springboard とまったく同じ外観が得られます。

2番目のアプローチ

私はこれについて考えましたが、私の意見では、設定する必要があります:

self.collectionView.pagingEnabled = YES;

をサブクラス化して、独自のコレクション ビュー レイアウトを作成しますUICollectionViewLayout。にアクセスできるカスタム レイアウト オブジェクトから、コレクション ビューのとのself.collectionViewサイズがわかります。その情報を使用して、セル(in ) およびを計算できます。カスタム レイアウトの作成に関するいくつかの記事を次に示します。framenumberOfSectionsnumberOfItemsInSection:framesprepareLayoutcollectionViewContentSize

3番目のアプローチ

カスタム レイアウトを作成せずに、これ (またはその概算) を行うことができます。空白のビューに追加UIScrollViewし、ページングを有効に設定します。スクロール ビューにコレクション ビューを追加します。次に、幅の制約を追加し、コードでアイテムの数をチェックしconstantて、正しい値に設定します(self.view.frame.size.width * numOfScreens)。外観は次のとおりです (セルの数字は を示していますindexPath.row): https://www.dropbox.com/s/ss4jdbvr511azxz/collection_view.movセルの順序に満足できない場合は、 1.または2.を使用する必要があります。

于 2013-10-17T19:49:19.937 に答える
15

このコードは、 Swift 3.1およびXcode 8.3.2でうまく機能します。

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        self.collectionView.collectionViewLayout = layout
        self.collectionView!.contentInset = UIEdgeInsets(top: -10, left: 0, bottom:0, right: 0)

        if let layout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.minimumInteritemSpacing = 0
            layout.minimumLineSpacing = 0
            layout.itemSize = CGSize(width: self.view.frame.size.width-40, height: self.collectionView.frame.size.height-10)
            layout.invalidateLayout()
        }

    }
于 2017-08-02T11:28:30.237 に答える
11

@Erik Hunter から、水平にするための完全なコードを投稿しますUICollectionView

UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.myCollectionView.collectionViewLayout = collectionViewFlowLayout;

スイフトで

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .Horizontal
self.myCollectionView.collectionViewLayout = layout

スウィフト 3.0 では

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
self.myCollectionView.collectionViewLayout = layout

この助けを願っています

于 2016-04-29T08:58:10.287 に答える
9

楽しみのために、別のアプローチは、ページングと水平スクロールのセットをそのままにして、配列項目の順序を変更して「上から下、左から右」から視覚的に「左から右、上から右」に変換するメソッドを追加することです。 bottom' を選択し、中間のセルを空の非表示セルで埋めて、間隔を正しくします。9 個のグリッドに 7 個のアイテムがある場合、これは次のようになります。

[1][4][7]
[2][5][ ]
[3][6][ ]

なるべき

[1][2][3]
[4][5][6]
[7][ ][ ]

つまり、1=1、2=4、3=7 など、6=空です。行と列の総数を計算して並べ替え、各セルの行と列の番号を計算し、列の行を変更し、その逆を行うと、新しいインデックスが得られます。セルに画像に対応する値がない場合は、空のセルを返しcell.hidden = YES;てそれに設定できます。

私が作成したサウンドボード アプリでは非常にうまく機能するので、動作するコードが必要な場合は追加します。このトリックを機能させるために必要なコードはほんのわずかです。実際よりも難しいように思えます。

アップデート

これが最善の解決策であるとは思えませんが、リクエストにより、ここに動作するコードがあります:

- (void)viewDidLoad {
    // Fill an `NSArray` with items in normal order
    items = [NSMutableArray arrayWithObjects:
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 1", @"label", @"Some value 1", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 2", @"label", @"Some value 2", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 3", @"label", @"Some value 3", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 4", @"label", @"Some value 4", @"value", nil],
             [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 5", @"label", @"Some value 5", @"value", nil],
              nil
              ];

    // Calculate number of rows and columns based on width and height of the `UICollectionView` and individual cells (you might have to add margins to the equation based on your setup!)
    CGFloat w = myCollectionView.frame.size.width;
    CGFloat h = myCollectionView.frame.size.height;
    rows = floor(h / cellHeight);
    columns = floor(w / cellWidth);
}

// Calculate number of sections
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return ceil((float)items.count / (float)(rows * columns));
}

// Every section has to have every cell filled, as we need to add empty cells as well to correct the spacing
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return rows*columns;
}

// And now the most important one
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier@"myIdentifier" forIndexPath:indexPath];

    // Convert rows and columns
    int row = indexPath.row % rows;
    int col = floor(indexPath.row / rows);
    // Calculate the new index in the `NSArray`
    int newIndex = ((int)indexPath.section * rows * columns) + col + row * columns;

    // If the newIndex is within the range of the items array we show the cell, if not we hide it
    if(newIndex < items.count) {
        NSDictionary *item = [items objectAtIndex:newIndex];
        cell.label.text = [item objectForKey:@"label"];
        cell.hidden = NO;
    } else {
        cell.hidden = YES;
    }

    return cell;
}

このメソッドを使用したい場合は、対応する項目を取得するためにdidSelectItemAtIndexPath使用したのと同じ変換を使用する必要があります。cellForItemAtIndexPathセルの余白がある場合は、行と列の計算にそれらを追加する必要があります。これが機能するには、それらが正しい必要があるためです。

于 2015-01-15T14:03:53.460 に答える
8

UICollectionView を使用して同じ Springboard の動作を行うことができます。そのためには、カスタム レイアウトのコードを記述する必要があります。

「SMCollectionViewFillLayout」を使用したカスタムレイアウトクラスの実装でそれを達成しました

コード リポジトリ:

https://github.com/smindia1988/SMCollectionViewFillLayout

以下のように出力します。

1.png

First.png

2_Code_H-Scroll_V-Fill.png

ここに画像の説明を入力

3_Output_H-Scroll_V-Fill.png ここに画像の説明を入力

4_Code_H-Scroll_H-Fill.png ここに画像の説明を入力

5_Output_H-Scroll_H-Fill.png ここに画像の説明を入力

于 2016-11-24T06:10:47.993 に答える
7

xcode 8の場合、私はこれを行いましたが、うまくいきました:

于 2016-12-22T20:10:40.437 に答える
6

私はXcode 6.2に取り組んでおり、水平スクロールのために属性インスペクターでスクロール方向を変更しました。

collectionView をクリック -> 属性インスペクター -> スクロール方向 -> 水平に変更

ここに画像の説明を入力誰かの役に立てば幸いです。

于 2015-03-25T10:22:26.980 に答える