Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UICollectionView没有';t在UITableViewCell内滚动_Ios_Swift_Uitableview_Uicollectionview_Uicollectionviewcell - Fatal编程技术网

Ios UICollectionView没有';t在UITableViewCell内滚动

Ios UICollectionView没有';t在UITableViewCell内滚动,ios,swift,uitableview,uicollectionview,uicollectionviewcell,Ios,Swift,Uitableview,Uicollectionview,Uicollectionviewcell,我在UITableViewCell内滚动UICollectionView时遇到问题 不幸的是,CollectionView根本没有滚动。当我尝试禁用其他UITableViewCells时,它可以正常工作,反之亦然 CollectionViewCell: import UIKit class CategoriesCollectionViewCell: UICollectionViewCell { override init(frame: CGRect) { super.i

我在UITableViewCell内滚动UICollectionView时遇到问题

不幸的是,CollectionView根本没有滚动。当我尝试禁用其他UITableViewCells时,它可以正常工作,反之亦然

CollectionViewCell:

import UIKit

class CategoriesCollectionViewCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layoutUI()
    }

    required init(coder adecoder: NSCoder) {
        fatalError("init(codeer:) has not been implemented")
    }

    lazy var categoriesImage: UIImageView = {
        let categoriesImage = UIImageView()
        categoriesImage.contentMode = .scaleToFill
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.image = UIImage(named: "pizza")
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.layer.masksToBounds = true
        categoriesImage.translatesAutoresizingMaskIntoConstraints = false
        return categoriesImage
    }()

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .black
        containerView.alpha = 0.7
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoryName: UILabel = {
        let categoryName = UILabel()
        categoryName.textColor = .white
        categoryName.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
        categoryName.text = "Soup"
        categoryName.textAlignment = .left
        categoryName.translatesAutoresizingMaskIntoConstraints = false
        return categoryName
    }()

    lazy var recipesNumber: UILabel = {
        let recipesNumber = UILabel()
        recipesNumber.textColor = .white
        recipesNumber.font = UIFont(name: "AvenirNext-Regular", size: 16)
        recipesNumber.text = "33"
        recipesNumber.textAlignment = .left
        recipesNumber.translatesAutoresizingMaskIntoConstraints = false
        return recipesNumber
    }()

    func setupcategoriesImageConstraints() {
        NSLayoutConstraint.activate([
            categoriesImage.topAnchor.constraint(equalTo: topAnchor),
            categoriesImage.bottomAnchor.constraint(equalTo: bottomAnchor),
            categoriesImage.leadingAnchor.constraint(equalTo: leadingAnchor),
            categoriesImage.trailingAnchor.constraint(equalTo: trailingAnchor),
        ])
    }

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: categoriesImage.topAnchor),
            containerView.bottomAnchor.constraint(equalTo: categoriesImage.bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: categoriesImage.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: categoriesImage.trailingAnchor)
        ])
    }

    func setupCategoryNameConstraints() {
        NSLayoutConstraint.activate([
            categoryName.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16),
            categoryName.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            categoryName.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func setuprecipesNumberConstraints() {
        NSLayoutConstraint.activate([
            recipesNumber.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            recipesNumber.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            recipesNumber.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func addSubviews() {
        addSubview(categoriesImage)
        categoriesImage.addSubview(containerView)
        containerView.addSubview(categoryName)
        containerView.addSubview(recipesNumber)
    }

    func layoutUI() {
        addSubviews()
        setupcategoriesImageConstraints()
        setupContainerViewConstraints()
        setupCategoryNameConstraints()
        setuprecipesNumberConstraints()
    }
}
import UIKit

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

    let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .clear
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoriesNameLabel: UILabel = {
        let categoriesNameLabel = UILabel()
        categoriesNameLabel.text = "Categories"
        categoriesNameLabel.textColor = .customDarkGray()
        categoriesNameLabel.textAlignment = .left
        categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
        categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
        return categoriesNameLabel
    }()

    lazy var seeAllCategoriesButton: UIButton = {
        let seeAllCategoriesButton = UIButton()
        seeAllCategoriesButton.setTitle("See all", for: .normal)
        seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
        seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
        seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
        seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
        return seeAllCategoriesButton
    }()

    @objc func test() {
        print("Test worked")
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
        return collectionView
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
        ])
    }

    func setupCategoriesNameLabelConstraints() {
        NSLayoutConstraint.activate([
            categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            categoriesNameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupSeeAllCategoriesButtonConstraints() {
        NSLayoutConstraint.activate([
            seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            seeAllCategoriesButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupCollectionViewConstraints() {
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: categoriesNameLabel.topAnchor, constant: 16),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 16),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func addSubviews() {
        addSubview(categoriesNameLabel)
        addSubview(containerView)
        containerView.addSubview(seeAllCategoriesButton)
        containerView.addSubview(collectionView)
    }

    func layoutUI() {
        addSubviews()
        setupCollectionViewConstraints()
        setupContainerViewConstraints()
        setupCategoriesNameLabelConstraints()
        setupSeeAllCategoriesButtonConstraints()
    }

}

extension CategoriesTableViewCellCollectionViewCell: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return categories.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoriesCollectionViewCell", for: indexPath) as! CategoriesCollectionViewCell

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.frame.width / 2, height: self.frame.width / 4)
    }

}
import UIKit

class HomeTableViewCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.layer.shadowColor = UIColor.black.cgColor
        containerView.layer.shadowOpacity = 1
        containerView.layer.shadowOffset = .init(width: 2, height: 2)
        containerView.layer.shadowRadius = 7.0
        containerView.layer.cornerRadius = 8.0
//        containerView.clipsToBounds = true
        return containerView
    }()

    lazy var foodImage: UIImageView = {
        let foodImage = UIImageView()
        foodImage.translatesAutoresizingMaskIntoConstraints = false
        foodImage.contentMode = .scaleAspectFill
        foodImage.clipsToBounds = true
        foodImage.layer.cornerRadius = 8.0
        return foodImage
    }()

    lazy var foodTitle: UILabel = {
        let foodTitle = UILabel()
        foodTitle.textColor = .CustomGreen()
        foodTitle.numberOfLines = 0
        foodTitle.translatesAutoresizingMaskIntoConstraints = false
        return foodTitle
    }()

    func setupContainerView() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func setupFoodImage() {
        NSLayoutConstraint.activate([
            foodImage.topAnchor.constraint(equalTo: containerView.topAnchor),
            foodImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            foodImage.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            foodImage.heightAnchor.constraint(equalToConstant: 250)
        ])
    }

    func setupFoodTitle() {
        NSLayoutConstraint.activate([
            foodTitle.topAnchor.constraint(equalTo: foodImage.bottomAnchor, constant: 16),
            foodTitle.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            foodTitle.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            foodTitle.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16)
        ])
    }

    func addSubview() {
        addSubview(containerView)
        containerView.addSubview(foodImage)
        containerView.addSubview(foodTitle)
    }

    func layoutUI() {
        addSubview()
        setupContainerView()
        setupFoodImage()
        setupFoodTitle()
    }

}
class HomeView: UIView {

    var recipes: Recipes?
    var recipesDetails = [Recipe]()
    let indicator = ActivityIndicator()

    override init( frame: CGRect) {
        super.init(frame: frame)
        layoutUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var foodTableView: UITableView = {
        let foodTableView = UITableView()
        foodTableView.translatesAutoresizingMaskIntoConstraints = false
        foodTableView.backgroundColor = .white
        foodTableView.delegate = self
        foodTableView.dataSource = self
        foodTableView.register(CategoriesTableViewCellCollectionViewCell.self, forCellReuseIdentifier: "CategoriesTableViewCellCollectionViewCell")
        foodTableView.register(HomeTableViewCell.self, forCellReuseIdentifier: "HomeTableViewCell")
        foodTableView.rowHeight = UITableView.automaticDimension
//        foodTableView.estimatedRowHeight = 100
        foodTableView.showsVerticalScrollIndicator = false
        foodTableView.separatorStyle = .none
        return foodTableView
    }()

    func setupFoodTableView() {
        NSLayoutConstraint.activate([
            foodTableView.topAnchor.constraint(equalTo: topAnchor),
            foodTableView.bottomAnchor.constraint(equalTo: bottomAnchor),
            foodTableView.leadingAnchor.constraint(equalTo: leadingAnchor),
            foodTableView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }

    func addSubview() {
        addSubview(foodTableView)
    }

    func layoutUI() {
        indicator.setupIndicatorView(self, containerColor: .customDarkGray(), indicatorColor: .white)
        addSubview()
        setupFoodTableView()
        fetchData()

    }

    func fetchData() {
        AF.request("https://api.url").responseJSON { (response) in
            if let error = response.error {
                print(error)
            }
            do {
                self.recipes = try JSONDecoder().decode(Recipes.self, from: response.data!)
                self.recipesDetails = self.recipes?.recipes ?? []
                DispatchQueue.main.async {
                    self.foodTableView.reloadData()
                }
            } catch {
                print(error)
            }
            self.indicator.hideIndicatorView()
        }
    }

}

extension HomeView: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return recipesDetails.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CategoriesTableViewCellCollectionViewCell", for: indexPath) as! CategoriesTableViewCellCollectionViewCell
            cell.layoutIfNeeded()
            cell.collectionView.reloadData()
            return cell
        }

        let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
        let url = URL(string: recipesDetails[indexPath.row].image ?? "Error")
        cell.foodImage.kf.setImage(with: url)
        cell.foodTitle.text = recipesDetails[indexPath.row].title
        cell.layoutIfNeeded()
        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == 0 {
            return 160

        } else {
            return 250
        }

    }

}
CollectionViewInTableViewCell:

import UIKit

class CategoriesCollectionViewCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layoutUI()
    }

    required init(coder adecoder: NSCoder) {
        fatalError("init(codeer:) has not been implemented")
    }

    lazy var categoriesImage: UIImageView = {
        let categoriesImage = UIImageView()
        categoriesImage.contentMode = .scaleToFill
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.image = UIImage(named: "pizza")
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.layer.masksToBounds = true
        categoriesImage.translatesAutoresizingMaskIntoConstraints = false
        return categoriesImage
    }()

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .black
        containerView.alpha = 0.7
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoryName: UILabel = {
        let categoryName = UILabel()
        categoryName.textColor = .white
        categoryName.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
        categoryName.text = "Soup"
        categoryName.textAlignment = .left
        categoryName.translatesAutoresizingMaskIntoConstraints = false
        return categoryName
    }()

    lazy var recipesNumber: UILabel = {
        let recipesNumber = UILabel()
        recipesNumber.textColor = .white
        recipesNumber.font = UIFont(name: "AvenirNext-Regular", size: 16)
        recipesNumber.text = "33"
        recipesNumber.textAlignment = .left
        recipesNumber.translatesAutoresizingMaskIntoConstraints = false
        return recipesNumber
    }()

    func setupcategoriesImageConstraints() {
        NSLayoutConstraint.activate([
            categoriesImage.topAnchor.constraint(equalTo: topAnchor),
            categoriesImage.bottomAnchor.constraint(equalTo: bottomAnchor),
            categoriesImage.leadingAnchor.constraint(equalTo: leadingAnchor),
            categoriesImage.trailingAnchor.constraint(equalTo: trailingAnchor),
        ])
    }

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: categoriesImage.topAnchor),
            containerView.bottomAnchor.constraint(equalTo: categoriesImage.bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: categoriesImage.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: categoriesImage.trailingAnchor)
        ])
    }

    func setupCategoryNameConstraints() {
        NSLayoutConstraint.activate([
            categoryName.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16),
            categoryName.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            categoryName.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func setuprecipesNumberConstraints() {
        NSLayoutConstraint.activate([
            recipesNumber.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            recipesNumber.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            recipesNumber.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func addSubviews() {
        addSubview(categoriesImage)
        categoriesImage.addSubview(containerView)
        containerView.addSubview(categoryName)
        containerView.addSubview(recipesNumber)
    }

    func layoutUI() {
        addSubviews()
        setupcategoriesImageConstraints()
        setupContainerViewConstraints()
        setupCategoryNameConstraints()
        setuprecipesNumberConstraints()
    }
}
import UIKit

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

    let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .clear
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoriesNameLabel: UILabel = {
        let categoriesNameLabel = UILabel()
        categoriesNameLabel.text = "Categories"
        categoriesNameLabel.textColor = .customDarkGray()
        categoriesNameLabel.textAlignment = .left
        categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
        categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
        return categoriesNameLabel
    }()

    lazy var seeAllCategoriesButton: UIButton = {
        let seeAllCategoriesButton = UIButton()
        seeAllCategoriesButton.setTitle("See all", for: .normal)
        seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
        seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
        seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
        seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
        return seeAllCategoriesButton
    }()

    @objc func test() {
        print("Test worked")
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
        return collectionView
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
        ])
    }

    func setupCategoriesNameLabelConstraints() {
        NSLayoutConstraint.activate([
            categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            categoriesNameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupSeeAllCategoriesButtonConstraints() {
        NSLayoutConstraint.activate([
            seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            seeAllCategoriesButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupCollectionViewConstraints() {
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: categoriesNameLabel.topAnchor, constant: 16),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 16),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func addSubviews() {
        addSubview(categoriesNameLabel)
        addSubview(containerView)
        containerView.addSubview(seeAllCategoriesButton)
        containerView.addSubview(collectionView)
    }

    func layoutUI() {
        addSubviews()
        setupCollectionViewConstraints()
        setupContainerViewConstraints()
        setupCategoriesNameLabelConstraints()
        setupSeeAllCategoriesButtonConstraints()
    }

}

extension CategoriesTableViewCellCollectionViewCell: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return categories.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoriesCollectionViewCell", for: indexPath) as! CategoriesCollectionViewCell

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.frame.width / 2, height: self.frame.width / 4)
    }

}
import UIKit

class HomeTableViewCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.layer.shadowColor = UIColor.black.cgColor
        containerView.layer.shadowOpacity = 1
        containerView.layer.shadowOffset = .init(width: 2, height: 2)
        containerView.layer.shadowRadius = 7.0
        containerView.layer.cornerRadius = 8.0
//        containerView.clipsToBounds = true
        return containerView
    }()

    lazy var foodImage: UIImageView = {
        let foodImage = UIImageView()
        foodImage.translatesAutoresizingMaskIntoConstraints = false
        foodImage.contentMode = .scaleAspectFill
        foodImage.clipsToBounds = true
        foodImage.layer.cornerRadius = 8.0
        return foodImage
    }()

    lazy var foodTitle: UILabel = {
        let foodTitle = UILabel()
        foodTitle.textColor = .CustomGreen()
        foodTitle.numberOfLines = 0
        foodTitle.translatesAutoresizingMaskIntoConstraints = false
        return foodTitle
    }()

    func setupContainerView() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func setupFoodImage() {
        NSLayoutConstraint.activate([
            foodImage.topAnchor.constraint(equalTo: containerView.topAnchor),
            foodImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            foodImage.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            foodImage.heightAnchor.constraint(equalToConstant: 250)
        ])
    }

    func setupFoodTitle() {
        NSLayoutConstraint.activate([
            foodTitle.topAnchor.constraint(equalTo: foodImage.bottomAnchor, constant: 16),
            foodTitle.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            foodTitle.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            foodTitle.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16)
        ])
    }

    func addSubview() {
        addSubview(containerView)
        containerView.addSubview(foodImage)
        containerView.addSubview(foodTitle)
    }

    func layoutUI() {
        addSubview()
        setupContainerView()
        setupFoodImage()
        setupFoodTitle()
    }

}
class HomeView: UIView {

    var recipes: Recipes?
    var recipesDetails = [Recipe]()
    let indicator = ActivityIndicator()

    override init( frame: CGRect) {
        super.init(frame: frame)
        layoutUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var foodTableView: UITableView = {
        let foodTableView = UITableView()
        foodTableView.translatesAutoresizingMaskIntoConstraints = false
        foodTableView.backgroundColor = .white
        foodTableView.delegate = self
        foodTableView.dataSource = self
        foodTableView.register(CategoriesTableViewCellCollectionViewCell.self, forCellReuseIdentifier: "CategoriesTableViewCellCollectionViewCell")
        foodTableView.register(HomeTableViewCell.self, forCellReuseIdentifier: "HomeTableViewCell")
        foodTableView.rowHeight = UITableView.automaticDimension
//        foodTableView.estimatedRowHeight = 100
        foodTableView.showsVerticalScrollIndicator = false
        foodTableView.separatorStyle = .none
        return foodTableView
    }()

    func setupFoodTableView() {
        NSLayoutConstraint.activate([
            foodTableView.topAnchor.constraint(equalTo: topAnchor),
            foodTableView.bottomAnchor.constraint(equalTo: bottomAnchor),
            foodTableView.leadingAnchor.constraint(equalTo: leadingAnchor),
            foodTableView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }

    func addSubview() {
        addSubview(foodTableView)
    }

    func layoutUI() {
        indicator.setupIndicatorView(self, containerColor: .customDarkGray(), indicatorColor: .white)
        addSubview()
        setupFoodTableView()
        fetchData()

    }

    func fetchData() {
        AF.request("https://api.url").responseJSON { (response) in
            if let error = response.error {
                print(error)
            }
            do {
                self.recipes = try JSONDecoder().decode(Recipes.self, from: response.data!)
                self.recipesDetails = self.recipes?.recipes ?? []
                DispatchQueue.main.async {
                    self.foodTableView.reloadData()
                }
            } catch {
                print(error)
            }
            self.indicator.hideIndicatorView()
        }
    }

}

extension HomeView: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return recipesDetails.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CategoriesTableViewCellCollectionViewCell", for: indexPath) as! CategoriesTableViewCellCollectionViewCell
            cell.layoutIfNeeded()
            cell.collectionView.reloadData()
            return cell
        }

        let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
        let url = URL(string: recipesDetails[indexPath.row].image ?? "Error")
        cell.foodImage.kf.setImage(with: url)
        cell.foodTitle.text = recipesDetails[indexPath.row].title
        cell.layoutIfNeeded()
        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == 0 {
            return 160

        } else {
            return 250
        }

    }

}
表格视图单元格:

import UIKit

class CategoriesCollectionViewCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layoutUI()
    }

    required init(coder adecoder: NSCoder) {
        fatalError("init(codeer:) has not been implemented")
    }

    lazy var categoriesImage: UIImageView = {
        let categoriesImage = UIImageView()
        categoriesImage.contentMode = .scaleToFill
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.image = UIImage(named: "pizza")
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.layer.masksToBounds = true
        categoriesImage.translatesAutoresizingMaskIntoConstraints = false
        return categoriesImage
    }()

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .black
        containerView.alpha = 0.7
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoryName: UILabel = {
        let categoryName = UILabel()
        categoryName.textColor = .white
        categoryName.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
        categoryName.text = "Soup"
        categoryName.textAlignment = .left
        categoryName.translatesAutoresizingMaskIntoConstraints = false
        return categoryName
    }()

    lazy var recipesNumber: UILabel = {
        let recipesNumber = UILabel()
        recipesNumber.textColor = .white
        recipesNumber.font = UIFont(name: "AvenirNext-Regular", size: 16)
        recipesNumber.text = "33"
        recipesNumber.textAlignment = .left
        recipesNumber.translatesAutoresizingMaskIntoConstraints = false
        return recipesNumber
    }()

    func setupcategoriesImageConstraints() {
        NSLayoutConstraint.activate([
            categoriesImage.topAnchor.constraint(equalTo: topAnchor),
            categoriesImage.bottomAnchor.constraint(equalTo: bottomAnchor),
            categoriesImage.leadingAnchor.constraint(equalTo: leadingAnchor),
            categoriesImage.trailingAnchor.constraint(equalTo: trailingAnchor),
        ])
    }

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: categoriesImage.topAnchor),
            containerView.bottomAnchor.constraint(equalTo: categoriesImage.bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: categoriesImage.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: categoriesImage.trailingAnchor)
        ])
    }

    func setupCategoryNameConstraints() {
        NSLayoutConstraint.activate([
            categoryName.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16),
            categoryName.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            categoryName.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func setuprecipesNumberConstraints() {
        NSLayoutConstraint.activate([
            recipesNumber.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            recipesNumber.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            recipesNumber.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func addSubviews() {
        addSubview(categoriesImage)
        categoriesImage.addSubview(containerView)
        containerView.addSubview(categoryName)
        containerView.addSubview(recipesNumber)
    }

    func layoutUI() {
        addSubviews()
        setupcategoriesImageConstraints()
        setupContainerViewConstraints()
        setupCategoryNameConstraints()
        setuprecipesNumberConstraints()
    }
}
import UIKit

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

    let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .clear
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoriesNameLabel: UILabel = {
        let categoriesNameLabel = UILabel()
        categoriesNameLabel.text = "Categories"
        categoriesNameLabel.textColor = .customDarkGray()
        categoriesNameLabel.textAlignment = .left
        categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
        categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
        return categoriesNameLabel
    }()

    lazy var seeAllCategoriesButton: UIButton = {
        let seeAllCategoriesButton = UIButton()
        seeAllCategoriesButton.setTitle("See all", for: .normal)
        seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
        seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
        seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
        seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
        return seeAllCategoriesButton
    }()

    @objc func test() {
        print("Test worked")
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
        return collectionView
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
        ])
    }

    func setupCategoriesNameLabelConstraints() {
        NSLayoutConstraint.activate([
            categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            categoriesNameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupSeeAllCategoriesButtonConstraints() {
        NSLayoutConstraint.activate([
            seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            seeAllCategoriesButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupCollectionViewConstraints() {
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: categoriesNameLabel.topAnchor, constant: 16),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 16),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func addSubviews() {
        addSubview(categoriesNameLabel)
        addSubview(containerView)
        containerView.addSubview(seeAllCategoriesButton)
        containerView.addSubview(collectionView)
    }

    func layoutUI() {
        addSubviews()
        setupCollectionViewConstraints()
        setupContainerViewConstraints()
        setupCategoriesNameLabelConstraints()
        setupSeeAllCategoriesButtonConstraints()
    }

}

extension CategoriesTableViewCellCollectionViewCell: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return categories.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoriesCollectionViewCell", for: indexPath) as! CategoriesCollectionViewCell

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.frame.width / 2, height: self.frame.width / 4)
    }

}
import UIKit

class HomeTableViewCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.layer.shadowColor = UIColor.black.cgColor
        containerView.layer.shadowOpacity = 1
        containerView.layer.shadowOffset = .init(width: 2, height: 2)
        containerView.layer.shadowRadius = 7.0
        containerView.layer.cornerRadius = 8.0
//        containerView.clipsToBounds = true
        return containerView
    }()

    lazy var foodImage: UIImageView = {
        let foodImage = UIImageView()
        foodImage.translatesAutoresizingMaskIntoConstraints = false
        foodImage.contentMode = .scaleAspectFill
        foodImage.clipsToBounds = true
        foodImage.layer.cornerRadius = 8.0
        return foodImage
    }()

    lazy var foodTitle: UILabel = {
        let foodTitle = UILabel()
        foodTitle.textColor = .CustomGreen()
        foodTitle.numberOfLines = 0
        foodTitle.translatesAutoresizingMaskIntoConstraints = false
        return foodTitle
    }()

    func setupContainerView() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func setupFoodImage() {
        NSLayoutConstraint.activate([
            foodImage.topAnchor.constraint(equalTo: containerView.topAnchor),
            foodImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            foodImage.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            foodImage.heightAnchor.constraint(equalToConstant: 250)
        ])
    }

    func setupFoodTitle() {
        NSLayoutConstraint.activate([
            foodTitle.topAnchor.constraint(equalTo: foodImage.bottomAnchor, constant: 16),
            foodTitle.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            foodTitle.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            foodTitle.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16)
        ])
    }

    func addSubview() {
        addSubview(containerView)
        containerView.addSubview(foodImage)
        containerView.addSubview(foodTitle)
    }

    func layoutUI() {
        addSubview()
        setupContainerView()
        setupFoodImage()
        setupFoodTitle()
    }

}
class HomeView: UIView {

    var recipes: Recipes?
    var recipesDetails = [Recipe]()
    let indicator = ActivityIndicator()

    override init( frame: CGRect) {
        super.init(frame: frame)
        layoutUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var foodTableView: UITableView = {
        let foodTableView = UITableView()
        foodTableView.translatesAutoresizingMaskIntoConstraints = false
        foodTableView.backgroundColor = .white
        foodTableView.delegate = self
        foodTableView.dataSource = self
        foodTableView.register(CategoriesTableViewCellCollectionViewCell.self, forCellReuseIdentifier: "CategoriesTableViewCellCollectionViewCell")
        foodTableView.register(HomeTableViewCell.self, forCellReuseIdentifier: "HomeTableViewCell")
        foodTableView.rowHeight = UITableView.automaticDimension
//        foodTableView.estimatedRowHeight = 100
        foodTableView.showsVerticalScrollIndicator = false
        foodTableView.separatorStyle = .none
        return foodTableView
    }()

    func setupFoodTableView() {
        NSLayoutConstraint.activate([
            foodTableView.topAnchor.constraint(equalTo: topAnchor),
            foodTableView.bottomAnchor.constraint(equalTo: bottomAnchor),
            foodTableView.leadingAnchor.constraint(equalTo: leadingAnchor),
            foodTableView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }

    func addSubview() {
        addSubview(foodTableView)
    }

    func layoutUI() {
        indicator.setupIndicatorView(self, containerColor: .customDarkGray(), indicatorColor: .white)
        addSubview()
        setupFoodTableView()
        fetchData()

    }

    func fetchData() {
        AF.request("https://api.url").responseJSON { (response) in
            if let error = response.error {
                print(error)
            }
            do {
                self.recipes = try JSONDecoder().decode(Recipes.self, from: response.data!)
                self.recipesDetails = self.recipes?.recipes ?? []
                DispatchQueue.main.async {
                    self.foodTableView.reloadData()
                }
            } catch {
                print(error)
            }
            self.indicator.hideIndicatorView()
        }
    }

}

extension HomeView: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return recipesDetails.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CategoriesTableViewCellCollectionViewCell", for: indexPath) as! CategoriesTableViewCellCollectionViewCell
            cell.layoutIfNeeded()
            cell.collectionView.reloadData()
            return cell
        }

        let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
        let url = URL(string: recipesDetails[indexPath.row].image ?? "Error")
        cell.foodImage.kf.setImage(with: url)
        cell.foodTitle.text = recipesDetails[indexPath.row].title
        cell.layoutIfNeeded()
        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == 0 {
            return 160

        } else {
            return 250
        }

    }

}
家庭视图:

import UIKit

class CategoriesCollectionViewCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layoutUI()
    }

    required init(coder adecoder: NSCoder) {
        fatalError("init(codeer:) has not been implemented")
    }

    lazy var categoriesImage: UIImageView = {
        let categoriesImage = UIImageView()
        categoriesImage.contentMode = .scaleToFill
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.image = UIImage(named: "pizza")
        categoriesImage.layer.cornerRadius = 8.0
        categoriesImage.layer.masksToBounds = true
        categoriesImage.translatesAutoresizingMaskIntoConstraints = false
        return categoriesImage
    }()

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .black
        containerView.alpha = 0.7
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoryName: UILabel = {
        let categoryName = UILabel()
        categoryName.textColor = .white
        categoryName.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
        categoryName.text = "Soup"
        categoryName.textAlignment = .left
        categoryName.translatesAutoresizingMaskIntoConstraints = false
        return categoryName
    }()

    lazy var recipesNumber: UILabel = {
        let recipesNumber = UILabel()
        recipesNumber.textColor = .white
        recipesNumber.font = UIFont(name: "AvenirNext-Regular", size: 16)
        recipesNumber.text = "33"
        recipesNumber.textAlignment = .left
        recipesNumber.translatesAutoresizingMaskIntoConstraints = false
        return recipesNumber
    }()

    func setupcategoriesImageConstraints() {
        NSLayoutConstraint.activate([
            categoriesImage.topAnchor.constraint(equalTo: topAnchor),
            categoriesImage.bottomAnchor.constraint(equalTo: bottomAnchor),
            categoriesImage.leadingAnchor.constraint(equalTo: leadingAnchor),
            categoriesImage.trailingAnchor.constraint(equalTo: trailingAnchor),
        ])
    }

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: categoriesImage.topAnchor),
            containerView.bottomAnchor.constraint(equalTo: categoriesImage.bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: categoriesImage.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: categoriesImage.trailingAnchor)
        ])
    }

    func setupCategoryNameConstraints() {
        NSLayoutConstraint.activate([
            categoryName.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16),
            categoryName.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            categoryName.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func setuprecipesNumberConstraints() {
        NSLayoutConstraint.activate([
            recipesNumber.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            recipesNumber.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            recipesNumber.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: 16)
        ])
    }

    func addSubviews() {
        addSubview(categoriesImage)
        categoriesImage.addSubview(containerView)
        containerView.addSubview(categoryName)
        containerView.addSubview(recipesNumber)
    }

    func layoutUI() {
        addSubviews()
        setupcategoriesImageConstraints()
        setupContainerViewConstraints()
        setupCategoryNameConstraints()
        setuprecipesNumberConstraints()
    }
}
import UIKit

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

    let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .clear
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoriesNameLabel: UILabel = {
        let categoriesNameLabel = UILabel()
        categoriesNameLabel.text = "Categories"
        categoriesNameLabel.textColor = .customDarkGray()
        categoriesNameLabel.textAlignment = .left
        categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
        categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
        return categoriesNameLabel
    }()

    lazy var seeAllCategoriesButton: UIButton = {
        let seeAllCategoriesButton = UIButton()
        seeAllCategoriesButton.setTitle("See all", for: .normal)
        seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
        seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
        seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
        seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
        return seeAllCategoriesButton
    }()

    @objc func test() {
        print("Test worked")
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
        return collectionView
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
        ])
    }

    func setupCategoriesNameLabelConstraints() {
        NSLayoutConstraint.activate([
            categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            categoriesNameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupSeeAllCategoriesButtonConstraints() {
        NSLayoutConstraint.activate([
            seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            seeAllCategoriesButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
    }

    func setupCollectionViewConstraints() {
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: categoriesNameLabel.topAnchor, constant: 16),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 16),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func addSubviews() {
        addSubview(categoriesNameLabel)
        addSubview(containerView)
        containerView.addSubview(seeAllCategoriesButton)
        containerView.addSubview(collectionView)
    }

    func layoutUI() {
        addSubviews()
        setupCollectionViewConstraints()
        setupContainerViewConstraints()
        setupCategoriesNameLabelConstraints()
        setupSeeAllCategoriesButtonConstraints()
    }

}

extension CategoriesTableViewCellCollectionViewCell: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return categories.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoriesCollectionViewCell", for: indexPath) as! CategoriesCollectionViewCell

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.frame.width / 2, height: self.frame.width / 4)
    }

}
import UIKit

class HomeTableViewCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.layer.shadowColor = UIColor.black.cgColor
        containerView.layer.shadowOpacity = 1
        containerView.layer.shadowOffset = .init(width: 2, height: 2)
        containerView.layer.shadowRadius = 7.0
        containerView.layer.cornerRadius = 8.0
//        containerView.clipsToBounds = true
        return containerView
    }()

    lazy var foodImage: UIImageView = {
        let foodImage = UIImageView()
        foodImage.translatesAutoresizingMaskIntoConstraints = false
        foodImage.contentMode = .scaleAspectFill
        foodImage.clipsToBounds = true
        foodImage.layer.cornerRadius = 8.0
        return foodImage
    }()

    lazy var foodTitle: UILabel = {
        let foodTitle = UILabel()
        foodTitle.textColor = .CustomGreen()
        foodTitle.numberOfLines = 0
        foodTitle.translatesAutoresizingMaskIntoConstraints = false
        return foodTitle
    }()

    func setupContainerView() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func setupFoodImage() {
        NSLayoutConstraint.activate([
            foodImage.topAnchor.constraint(equalTo: containerView.topAnchor),
            foodImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            foodImage.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            foodImage.heightAnchor.constraint(equalToConstant: 250)
        ])
    }

    func setupFoodTitle() {
        NSLayoutConstraint.activate([
            foodTitle.topAnchor.constraint(equalTo: foodImage.bottomAnchor, constant: 16),
            foodTitle.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16),
            foodTitle.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            foodTitle.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16)
        ])
    }

    func addSubview() {
        addSubview(containerView)
        containerView.addSubview(foodImage)
        containerView.addSubview(foodTitle)
    }

    func layoutUI() {
        addSubview()
        setupContainerView()
        setupFoodImage()
        setupFoodTitle()
    }

}
class HomeView: UIView {

    var recipes: Recipes?
    var recipesDetails = [Recipe]()
    let indicator = ActivityIndicator()

    override init( frame: CGRect) {
        super.init(frame: frame)
        layoutUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var foodTableView: UITableView = {
        let foodTableView = UITableView()
        foodTableView.translatesAutoresizingMaskIntoConstraints = false
        foodTableView.backgroundColor = .white
        foodTableView.delegate = self
        foodTableView.dataSource = self
        foodTableView.register(CategoriesTableViewCellCollectionViewCell.self, forCellReuseIdentifier: "CategoriesTableViewCellCollectionViewCell")
        foodTableView.register(HomeTableViewCell.self, forCellReuseIdentifier: "HomeTableViewCell")
        foodTableView.rowHeight = UITableView.automaticDimension
//        foodTableView.estimatedRowHeight = 100
        foodTableView.showsVerticalScrollIndicator = false
        foodTableView.separatorStyle = .none
        return foodTableView
    }()

    func setupFoodTableView() {
        NSLayoutConstraint.activate([
            foodTableView.topAnchor.constraint(equalTo: topAnchor),
            foodTableView.bottomAnchor.constraint(equalTo: bottomAnchor),
            foodTableView.leadingAnchor.constraint(equalTo: leadingAnchor),
            foodTableView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }

    func addSubview() {
        addSubview(foodTableView)
    }

    func layoutUI() {
        indicator.setupIndicatorView(self, containerColor: .customDarkGray(), indicatorColor: .white)
        addSubview()
        setupFoodTableView()
        fetchData()

    }

    func fetchData() {
        AF.request("https://api.url").responseJSON { (response) in
            if let error = response.error {
                print(error)
            }
            do {
                self.recipes = try JSONDecoder().decode(Recipes.self, from: response.data!)
                self.recipesDetails = self.recipes?.recipes ?? []
                DispatchQueue.main.async {
                    self.foodTableView.reloadData()
                }
            } catch {
                print(error)
            }
            self.indicator.hideIndicatorView()
        }
    }

}

extension HomeView: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return recipesDetails.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CategoriesTableViewCellCollectionViewCell", for: indexPath) as! CategoriesTableViewCellCollectionViewCell
            cell.layoutIfNeeded()
            cell.collectionView.reloadData()
            return cell
        }

        let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
        let url = URL(string: recipesDetails[indexPath.row].image ?? "Error")
        cell.foodImage.kf.setImage(with: url)
        cell.foodTitle.text = recipesDetails[indexPath.row].title
        cell.layoutIfNeeded()
        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == 0 {
            return 160

        } else {
            return 250
        }

    }

}
谁能告诉我问题出在哪里,或者我做错了什么


谢谢。

您无法滚动收藏视图,因为它超出了superview的范围。在代码中,有以下行:

containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
这使得您的
containerView
height仅为20分左右,但您的集合视图也是
containerView
的子视图

下面是您的代码在我看来的样子(基本上是这样的):

而且,我无法滚动收藏视图

您可以通过给
containerView
一个背景色(我用的是青色)来确认它在
containerView
界限之外:

您还可以通过设置
containerView.clipsToBounds=true来确认:

现在,我们甚至没有看到集合视图

您还有一些其他的约束问题,但它们与无法滚动集合视图没有关系

您的布局也有点混乱,因为您的
Categories
标签位于
containerView
之外。。。在
containerView
中添加标签+全部查看按钮+集合视图All似乎更有意义

我对您的
分类表ViewCellCollectionViewCell
做了一些编辑,解决了这个问题——我认为这已经接近您的最终目标了。你可能需要做一些调整,但希望它能给你一个好的方向

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

    let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .clear
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoriesNameLabel: UILabel = {
        let categoriesNameLabel = UILabel()
        categoriesNameLabel.text = "Categories"
        categoriesNameLabel.textColor = .gray // .customDarkGray()
        categoriesNameLabel.textAlignment = .left
        categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
        categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
        return categoriesNameLabel
    }()

    lazy var seeAllCategoriesButton: UIButton = {
        let seeAllCategoriesButton = UIButton()
        seeAllCategoriesButton.setTitle("See all", for: .normal)
//      seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
        seeAllCategoriesButton.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0), for: .normal)
        seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
        seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
        seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
        return seeAllCategoriesButton
    }()

    @objc func test() {
        print("Test worked")
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
        return collectionView
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            // should not be constrained to categoriesNameLabel height
            //containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
            // constrain 16-pts from bottom of cell
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16)
        ])
    }

    func setupCategoriesNameLabelConstraints() {
        NSLayoutConstraint.activate([
            categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            // centerY to seeAllCategoriesButton
            categoriesNameLabel.centerYAnchor.constraint(equalTo: seeAllCategoriesButton.centerYAnchor)
        ])
    }

    func setupSeeAllCategoriesButtonConstraints() {
        NSLayoutConstraint.activate([
            seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            // constrain top to containerView top
            seeAllCategoriesButton.topAnchor.constraint(equalTo: containerView.topAnchor)
        ])
    }

    func setupCollectionViewConstraints() {
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: seeAllCategoriesButton.bottomAnchor, constant: 0),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func addSubviews() {
        // but categoriesNameLabel inside containerView
        //addSubview(categoriesNameLabel)
        addSubview(containerView)
        containerView.addSubview(categoriesNameLabel)
        containerView.addSubview(seeAllCategoriesButton)
        containerView.addSubview(collectionView)
    }

    func layoutUI() {
        addSubviews()
        setupCollectionViewConstraints()
        setupContainerViewConstraints()
        setupCategoriesNameLabelConstraints()
        setupSeeAllCategoriesButtonConstraints()
    }

}
结果如下所示-您可以看到我已稍微滚动了一下集合视图:


无法滚动收藏视图,因为它超出了superview的范围。在代码中,有以下行:

containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
这使得您的
containerView
height仅为20分左右,但您的集合视图也是
containerView
的子视图

下面是您的代码在我看来的样子(基本上是这样的):

而且,我无法滚动收藏视图

您可以通过给
containerView
一个背景色(我用的是青色)来确认它在
containerView
界限之外:

您还可以通过设置
containerView.clipsToBounds=true来确认:

现在,我们甚至没有看到集合视图

您还有一些其他的约束问题,但它们与无法滚动集合视图没有关系

您的布局也有点混乱,因为您的
Categories
标签位于
containerView
之外。。。在
containerView
中添加标签+全部查看按钮+集合视图All似乎更有意义

我对您的
分类表ViewCellCollectionViewCell
做了一些编辑,解决了这个问题——我认为这已经接近您的最终目标了。你可能需要做一些调整,但希望它能给你一个好的方向

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

    let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutUI()
        selectionStyle = .none
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .clear
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var categoriesNameLabel: UILabel = {
        let categoriesNameLabel = UILabel()
        categoriesNameLabel.text = "Categories"
        categoriesNameLabel.textColor = .gray // .customDarkGray()
        categoriesNameLabel.textAlignment = .left
        categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
        categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
        return categoriesNameLabel
    }()

    lazy var seeAllCategoriesButton: UIButton = {
        let seeAllCategoriesButton = UIButton()
        seeAllCategoriesButton.setTitle("See all", for: .normal)
//      seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
        seeAllCategoriesButton.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0), for: .normal)
        seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
        seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
        seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
        return seeAllCategoriesButton
    }()

    @objc func test() {
        print("Test worked")
    }

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
        return collectionView
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            // should not be constrained to categoriesNameLabel height
            //containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
            // constrain 16-pts from bottom of cell
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16)
        ])
    }

    func setupCategoriesNameLabelConstraints() {
        NSLayoutConstraint.activate([
            categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            // centerY to seeAllCategoriesButton
            categoriesNameLabel.centerYAnchor.constraint(equalTo: seeAllCategoriesButton.centerYAnchor)
        ])
    }

    func setupSeeAllCategoriesButtonConstraints() {
        NSLayoutConstraint.activate([
            seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            // constrain top to containerView top
            seeAllCategoriesButton.topAnchor.constraint(equalTo: containerView.topAnchor)
        ])
    }

    func setupCollectionViewConstraints() {
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: seeAllCategoriesButton.bottomAnchor, constant: 0),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
        ])
    }

    func addSubviews() {
        // but categoriesNameLabel inside containerView
        //addSubview(categoriesNameLabel)
        addSubview(containerView)
        containerView.addSubview(categoriesNameLabel)
        containerView.addSubview(seeAllCategoriesButton)
        containerView.addSubview(collectionView)
    }

    func layoutUI() {
        addSubviews()
        setupCollectionViewConstraints()
        setupContainerViewConstraints()
        setupCategoriesNameLabelConstraints()
        setupSeeAllCategoriesButtonConstraints()
    }

}
结果如下所示-您可以看到我已稍微滚动了一下集合视图:


非常感谢您的帮助。你能帮我解决另一个问题吗?这是UITableViewCell的高度,它已损坏,我看不出我所做的错误。@AhmedAbdElaziz-我在这里发布了一整套类:。。。我的问题是我直接在单元格中添加了集合视图,但现在我先在容器视图中添加了容器视图,然后在容器视图中添加了集合视图,它像一个角色一样工作。非常感谢您的帮助。你能帮我解决另一个问题吗?这是UITableViewCell的高度,它已损坏,我看不出我所做的错误。@AhmedAbdElaziz-我在这里发布了一整套类:。。。看看这是否为您提供了所需的布局。谢谢它为我工作。我的问题是,我直接在单元格中添加了集合视图,但现在我先添加了容器视图,然后在容器视图中添加了集合视图,它的工作非常出色