質問: String(indexPath.row + 1) return cell } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } ``` ■Main.storyboardのキャプチャ ![画像の説明をここに入力](https://i.stack.imgur.com/sMxH4.png) ■実行結果(セルが1個のとき) ![画像の説明をここに入力](https://i.stack.imgur.com/SEWHy.png) ■実行結果(セルが2個のとき) ![画像の説明をここに入力](https://i.stack.imgur.com/O9j5n.png)
回答: `UICollectionView`と標準の`UICollectionViewFlowLayout`の組み合わせは、かなり多機能なので、適当なプロパティの値を設定すれば、ご説明のようなありがちなレイアウトは実現できるだろうと思ったのですが、リファレンスをちょっと探しただけではそれっぽいものは見つかりませんでした。 **uicollectionview center cells horizontally** 辺りで検索すると、本家Stack Overflowにいくつかのスレッドが見つかりました。 How to center horizontally UICollectionView Cells? How to center align the cells of a UICollectionView in Swift3.0? 基本的にはみな`UICollectionViewDelegateFlowLayout`に定義されたメソッドを実装して、左右の余白を自前で計算することで実現しなさいと言うことのようです。 以下のコードはその中の回答の一つを焼き直したものです(変数名やコメントの修正だけで本質的には同じ内容)。 なお、このコードが動作するためには`UICollectionView`の`delegate`を`ViewController`のインスタンスに設定している必要があります。`dataSource`の方はstoryboardで設定を行われたものと思いますので、未接続でしたら、同じ手順で`delegate`の方も`ViewController`に接続しておいてください。 ``` //標準のFlowLayoutを使用するものとして、UICollectionViewDelegateFlowLayoutに適合させる class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { //... 以下のメソッドの追加だけで、他の部分はそのままで良いはず //UICollectionViewDelegateFlowLayoutに定義されたメソッド //セクションごとに上下左右の余白を示すUIEdgeInsetsを返す func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout, case let numItems = collectionView.numberOfItems(inSection: section), numItems > 0 else { return .zero } //1セクション分の表示幅の計算(セルを可変サイズにする場合などは要修正) let minSpacing = flowLayout.minimumInteritemSpacing let itemWidth = flowLayout.itemSize.width let minSectionWidth = itemWidth * CGFloat(numItems) + minSpacing * CGFloat(numItems-1) //CollectionViewのコンテンツ領域の幅の計算 let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right //デフォルトのInsetsの取得 var insets = flowLayout.sectionInset //セクションの表示幅がコンテンツ領域より小さい時には余白を計算 if minSectionWidth < contentWidth { let paddingWidth = (contentWidth - minSectionWidth)/2 insets.left = paddingWidth insets.right = paddingWidth } return insets } } ``` 注意点としては、 * 設定項目の全てを全く同じに合わせたわけではないので、あちこち微修正が必要かもしれない (サイズなど、ご質問では表示されていない項目も多数ありますし...。) * 「セルが3個以上の際は、セルの1個目を左端に配置し、スクロールできる状態に」と明記されているが、このコードではセルが3個以上でも画面に収まる場合にはセンタリングして表示する と言う作りになっています。 こちらの環境で適当に設定したプロジェクトでは期待通りに動いているのですが、上記したように、そちらのプロジェクトに合わせるためには若干修正が必要かもしれません。お試しください。