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で繋ぎます。
TableViewCell
ShopTableViewCell.xib中にUICollectionViewを配置し、ShopTableViewCell.swiftへOutletで繋ぎます。
繋いだものに、ShopCollectionViewCellのxibの登録と、CollectionViewのDelegateの設定を行います。
DelegateはあくまでViewControllerの方で呼び出すので、ここではメソッドだけ記述します。
コードは以下です。
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を登録します。
@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の設定をします。
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")
}
}