iOS開発メモ6 (MediaUploaderの開発2)

関連する過去の投稿

iOS開発メモ5 (MediaUploaderの開発1)
iOS開発メモ4 (MediaUploaderの設計)

前回までの開発で、コレクションビューに画像を、とりあえずでタイル表示するところまでは可能になった。今回はセルの大きさを画面サイズから算出して、プログラミングで配列させてみる。( Auto Layoutは今回使用しない )

UICollectionViewDelegateFlowLayoutでセルのレイアウトをカスタマイズする

CollectionViewのセルのサイズやレイアウトをカスタマイズするためには、UICollectionViewDelegateFlowLayoutをオーバーライドして、各種サイズを算出して返してやる必要がある。

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

セルのサイズをCGSize型で返す。

sizeForItemAt

func collectionView(_ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    minimumInteritemSpacingForSectionAt section: Int) -> CGFloat

セルとセルの間の列幅をCGFloat型で返す。外周部分は後述するinsetForSectionAtで指定する。
指定したセルの幅だと枠内で収まらない場合、次の行で表示される。その為、右端には余った余白が表示されるが、これは本メソッドで指示できないので、隙間が嫌なら隙間を作らないようなセルサイズと個数にしてやる必要がある。

minimumInteritemSpacingForSectionAt

func collectionView(_ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    minimumLineSpacingForSectionAt section: Int) -> CGFloat

セルとセルの行間をCGFloatで指定する。

minimumLineSpacingForSectionAt

func collectionView(_ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    insetForSectionAt section: Int) -> UIEdgeInsets

セルのグループを囲むマージンの大きさを指定する。

insetForSectionAt

とりあえず縦方向を基準にして、1行当たりセルを3つ並べるレイアウトにする。
FirstViewControllerのメンバ変数にNUMBER_OF_HORIZONTAL_CELL_COUNTCELL_MARGINEDGE_INSETSを追加する。

class FirstViewController: UIViewController {
    :
    let NUMBER_OF_HORIZONTAL_CELL_COUNT = 3.0
    let CELL_MARGIN = 1.0
    let EDGE_INSETS = UIEdgeInsets(top:0, left:0, bottom:0, right:0)

    override func viewDidLoad() {

UICollectionViewDelegateFlowLayoutをFirstViewControllerのエクステンションとして実装する。

//----------------------------------------
// extension : UICollectionViewDelegateFlowLayout
//----------------------------------------
extension FirstViewController : UICollectionViewDelegateFlowLayout {

    // sizeForItemAt (セルサイズ)
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
        sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        // collectionViewの幅から指定するマージン分を引いたセルを詰めるエリアを算出
        var collectionBoundSize = collectionView.bounds.size
        collectionBoundSize.width -= EDGE_INSETS.left
        collectionBoundSize.width -= EDGE_INSETS.right
        collectionBoundSize.height -= EDGE_INSETS.top
        collectionBoundSize.height -= EDGE_INSETS.bottom
        
        // 水平方向のセル間の隙間の合計
        let cell_spacing =  CELL_MARGIN * ( NUMBER_OF_HORIZONTAL_CELL_COUNT - 1 )
        // 水平方向のセルの幅を算出
        let cell_length = (collectionBoundSize.width - CGFloat( cell_spacing ) ) / CGFloat(NUMBER_OF_HORIZONTAL_CELL_COUNT)
        // 正方形とするので、widthとheightを同じ値にする
        return CGSize( width: cell_length, height: cell_length )
    }

    // minimumLineSpacingForSectionAt (行間)
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
        minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        
        return CGFloat(CELL_MARGIN)
    }

    // minimumInteritemSpacingForSectionAt (列間)
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
        minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        
        return CGFloat(CELL_MARGIN)
    }

    // insetForSectionAt (外周)
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
        insetForSectionAt section: Int) -> UIEdgeInsets {
        
        return EDGE_INSETS
    } 
    
}

アプリケーションをビルドして、シミュレータで結果を確認する。
ちゃんと横3列で表示されることがわかる。

ss--2017-10-26-0.17.01