post Image
UITableViewCellにCollectionViewを入れる

Putting a UICollectionView in a UITableViewCell in Swiftに記載されている内容です。
今回xibを使っているので、上記サイトを踏まえて実装をしました。

階層は

  • ViewController (HomeViewController.swift)
  • TableView(ShopTableView.swift)
  • TableViewCell(ShopTableViewCell.swift)
  • CollectionView(ShopCollectionView.swift)
  • CollectionViewCell(ShopCollectionViewCell.swift)

の順番です。

CollectionViewCell

ShopCollectionViewCell.xibに画面へ反映したいものを作ります。
パーツはそれぞれShopCollectionViewCell.swiftにOutletで繋ぎます。

collectionViewCell.png

TableViewCell

ShopTableViewCell.xib中にUICollectionViewを配置し、ShopTableViewCell.swiftへOutletで繋ぎます。

tableViewCell.png

繋いだものに、ShopCollectionViewCellのxibの登録と、CollectionViewのDelegateの設定を行います。
DelegateはあくまでViewControllerの方で呼び出すので、ここではメソッドだけ記述します。

コードは以下です。

ShopTableViewCell.swift

class ShopTableViewCell: UITableViewCell {

    @IBOutlet weak var shopCollectionView: UICollectionView!

    override func awakeFromNib() {
        super.awakeFromNib()

        // xibファイルの登録
        let nib = UINib(nibName: "ShopCollectionViewCell", bundle: nil) // カスタムセルクラス名で`nib`を作成する
        shopCollectionView.register(nib, forCellWithReuseIdentifier: "ShopCollectionViewCell")
        // Initialization code
    }

    func setCollectionViewDataSourceDelegate
        <D: UICollectionViewDataSource & UICollectionViewDelegate>
        (dataSourceDelegate: D, forRow row: Int) {

        shopCollectionView.delegate = dataSourceDelegate
        shopCollectionView.dataSource = dataSourceDelegate
        shopCollectionView.reloadData()

    }
}

ViewController

HomeViewController.swiftに、storybord上でUITableViewを配置し、outletで繋ぎます。
繋いだものにShopTableViewCellのxibを登録します。

HomeViewController.swift

@IBOutlet weak var homeTableView: UITableView!

class HomeViewController: UIViewController {
    @IBOutlet weak var homeTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        homeTableView.delegate = self
        homeTableView.dataSource = self        

        let nib = UINib(nibName: "ShopTableViewCell", bundle: nil)
        homeTableView.register(nib, forCellReuseIdentifier: "ShopTableViewCell")

    }
}

CollectionViewとTableViewのDelegateの設定をします。

HomeViewController.swift

extension HomeViewController:  UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        guard let cell = cell as? ShopTableViewCell else { return }

        //ShopTableViewCell.swiftで設定したメソッドを呼び出す
        cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
    }

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCell(withIdentifier: "ShopTableViewCell", for: indexPath) as! ShopTableViewCell

        return cell
   }

}


extension HomeViewController: UICollectionViewDataSource, UICollectionViewDelegate{

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ShopCollectionViewCell", for: indexPath) as! ShopCollectionViewCell

        cell.shopName.text = homeData.topPickUpData[indexPath.row].shopName
        cell.shopThumb.image = UIImage.init(named: "shop.png")

    }
} 

『 Swift 』Article List