web-dev-qa-db-ja.com

自動レイアウトを使用してコレクションビューのセルサイズを設定する方法

こんにちは、auto layoutを使用してセルのサイズを変更しようとしています。

セルを3行3列で表示したい。

最初のセルの左マージン= 0

最終セルの右マージン= 0

そして、セルのすべてのスペースは1ptです。 instagramのように。

enter image description here

enter image description here

セルのサイズに設定する必要がありますか? Autolayoutを使用して制約を設定します。

また、コードを使用してセルのサイズを設定しようとしています。

ここに私のコードがあります:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSizeMake(123, 123);
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1;
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1;
}

しかし..私はそれがセルのサイズを正確に計算していないと思います。

画面のサイズに応じてセルのサイズを設定するにはどうすればよいですか?

セルの間に1ポイントのスペースを設定する必要があります。

ストーリーボードのみを使用して設定する方法はありますか?

そうでない場合、コードでどのように設定しますか?

ありがとうございました。

17
Shawn Baek

実行時にオンザフライで作成されるコレクションビューセルなどの繰り返しアイテムに制約を設定できないため、ストーリーボードのみを使用してサイズを設定できるとは思わない。

与えられた情報からサイズを簡単に計算できます。 collectionView(_:layout:sizeForItemAt:)では、collectionViewの境界にアクセスして、セルの目的のサイズを計算できます。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    // Compute the dimension of a cell for an NxN layout with space S between
    // cells.  Take the collection view's width, subtract (N-1)*S points for
    // the spaces between the cells, and then divide by N to find the final
    // dimension for the cell's width and height.

    let cellsAcross: CGFloat = 3
    let spaceBetweenCells: CGFloat = 1
    let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
    return CGSize(width: dim, height: dim)
}

これは、すべてのサイズのiPhoneおよびiPadで機能します。

24
vacawama

Vacawamaによる素晴らしい回答ですが、2つの問題がありました。ストーリーボードで定義した間隔が自動的に使用されるようにしました。

enter image description here

第二に、この関数を呼び出すことができず、誰もその方法について言及していませんでしたか? collectionViewのsizeForItemAtを呼び出すには、UICollectionViewDelegateを拡張する代わりにUICollectionViewDelegateFlowLayoutを拡張する必要があります。これにより、他の人の時間が節約されることを願っています。

extension MyViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let cellsAcross: CGFloat = 3
        var widthRemainingForCellContent = collectionView.bounds.width
        if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout {
            let borderSize: CGFloat = flowLayout.sectionInset.left + flowLayout.sectionInset.right
            widthRemainingForCellContent -= borderSize + ((cellsAcross - 1) * flowLayout.minimumInteritemSpacing)
        }
        let cellWidth = widthRemainingForCellContent / cellsAcross
        return CGSize(width: cellWidth, height: cellWidth)
    }

}
13
Travis M.

CollectionViewのデリゲートメソッドを使用して設定しました。これにより2xNのセットアップが可能になりますが、代わりに3xNにすることも簡単にできます。これがスクリーンショットです。GitHubで私のプロジェクトを参照できます...

https://github.com/WadeSellers/GoInstaPro

CollectionView flow layout screenshot

7
Wade Sellers

Swift 3バージョンコード vacawamaの回答に基づく:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let cellsAcross: CGFloat = 3
        let spaceBetweenCells: CGFloat = 1
        let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross

        return CGSize(width: dim, height: dim)
    }
4
mriaz0011

別のソリューションを次に示しますが、iPhone6でのみ機能します。

Iphone5/6plusの更新を試みます

@vacawamaに感謝します!

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {


        // Compute the dimension of a cell for an NxN layout with space S between
        // cells.  Take the collection view's width, subtract (N-1)*S points for
        // the spaces between the cells, and then divide by N to find the final
        // dimension for the cell's width and height.

        let cellsAcross: CGFloat = 3
        let spaceBetweenCells: CGFloat = 1
        let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
                print(indexPath.row)

        var width = dim

        //last cell's width
        if(  (indexPath.row + 1) % 3 == 0){
            width = 124

        }else {
            width = 124.5
        }
        print(width)
        return CGSizeMake(width, dim)

    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1;
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1;
    }
0
Shawn Baek