我正在尝试创建一个可以水平和垂直滚动的UICollectionView。

这是我的代码:

这是模型:

import UIKit

class AppCategory: NSObject {
    var name: String?
    var apps: [App]?

    static func sampleAppCategories() -> [AppCategory] {

        // Chapter 1
        let chapter1 = AppCategory()
        chapter1.name = NSLocalizedString("CHAPTER 1: ", comment: "1") + NSLocalizedString("19 Sections", comment: "title")

        var apps1 = [App]()

        let chapter1App = App()
        chapter1App.imageName = "IMG_2487"

        let chapter11App = App()
        chapter11App.imageName = "IMG_2502"

        let chapter12App = App()
        chapter12App.imageName = "IMG_2507"

        apps1.append(chapter1App)
        apps1.append(chapter11App)
         apps1.append(chapter12App)

        chapter1.apps = apps1

      // Chapter 2

        let chapter2 = AppCategory()
        chapter2.name = NSLocalizedString("CHAPTER 2: ", comment: "2") + NSLocalizedString("19 Sections", comment: "title")

        var apps2 = [App]()

        let chapter2App = App()
        chapter2App.imageName = "IMG_2508"


        apps2.append(chapter2App)

        chapter2.apps = apps2

        // Chapter 3

        let chapter3 = AppCategory()
        chapter3.name = NSLocalizedString("CHAPTER 3: ", comment: "title") + NSLocalizedString("19 Sections", comment: "title")


        var apps3 = [App]()

        let chapter3App = App()
        chapter3App.imageName = "IMG_2510"

        apps3.append(chapter3App)

        chapter3.apps = apps3

        // Chapter 4

        let chapter4 = AppCategory()
        chapter4.name = NSLocalizedString("CHAPTER 4: ", comment: "title") + NSLocalizedString("19 Sections", comment: "title")

        var apps4 = [App]()

        let chapter4App = App()
        chapter4App.imageName = "IMG_2511"

        apps4.append(chapter4App)

        chapter4.apps = apps4


        return [chapter1, chapter2, chapter3, chapter4]
    }

}


class App: NSObject {
    var imageName: String?
}


这是FeatureViewController:

import UIKit

class FeaturedViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {



    var appCategories: [AppCategory]?

    let verticalCellId = "verticalCellId"
    let horizontalCellId = "horizontalCellId"

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView?.backgroundColor = .white

        appCategories = AppCategory.sampleAppCategories()

        navigationItem.title = NSLocalizedString("Original", comment: "Original")
        navigationController?.navigationBar.prefersLargeTitles = true

         collectionView?.register(FeaturedVerticalCell.self, forCellWithReuseIdentifier: verticalCellId)


    }




    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let count = appCategories?.count {
            return count
        }
        return 0
    }

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

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: verticalCellId, for: indexPath) as! FeaturedVerticalCell
        cell.appCategory = appCategories?[indexPath.item]
        return cell
    }

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





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


        switch UIDevice.current.userInterfaceIdiom {
        case .phone:
            collectionView.reloadData()
            return CGSize(width:view.frame.width, height: view.frame.width / 5 * 4 )
        case .pad:
            let padding: CGFloat =  50
            let collectionViewSize = collectionView.frame.size.width - padding
            collectionView.reloadData()
            return CGSize(width: collectionViewSize / 5 * 4, height: collectionViewSize / 5 * 3 )
        case .tv:
            break
        case .carPlay:
            break
        case .unspecified:
            break

        }
        return CGSize(width: 0, height: 0)

    }

}


这是FeaturedVerticalCell:

import UIKit


struct Titles {
    var title: String?
    var images:[String]
}


class FeaturedVerticalCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    let horizontalCellId = "horizontalCellId"


    var appCategory: AppCategory? {
        didSet {
            if let name = appCategory?.name {
                titleLabel.text = name
            }
        }
    }



    let horizontalCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = UIColor.clear
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        return collectionView
    }()




    let titleLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        if UIDevice.current.userInterfaceIdiom == .phone {
            label.font = UIFont.systemFont(ofSize: 14.0, weight: UIFont.Weight.medium)
        } else {
            label.font = UIFont.systemFont(ofSize: 20.0, weight: UIFont.Weight.medium)
        }
        label.textAlignment = .left
        label.textColor = UIColor.darkGray
        return label
    }()



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

        horizontalCollectionView.dataSource = self
        horizontalCollectionView.delegate = self
        horizontalCollectionView.register(HorizontalCollectionViewCell.self, forCellWithReuseIdentifier: horizontalCellId)


        addSubview(horizontalCollectionView)
        horizontalCollectionView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 24).isActive = true
        horizontalCollectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 36).isActive = true
        horizontalCollectionView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -24).isActive = true
        horizontalCollectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 8).isActive = true



        addSubview(titleLabel)
        titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 24).isActive = true
        titleLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -24).isActive = true
        titleLabel.bottomAnchor.constraint(equalTo: horizontalCollectionView.topAnchor, constant: 0).isActive = true
        titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 24).isActive = true





    }


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



  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let count = appCategory?.apps?.count {
            return count
        }

        return 0

    }




    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell =  collectionView.dequeueReusableCell(withReuseIdentifier: horizontalCellId, for: indexPath) as! HorizontalCollectionViewCell
        cell.app = appCategory?.apps?[indexPath.item]
        return cell


    }

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



}




class HorizontalCollectionViewCell: UICollectionViewCell {

    var app: App? {
        didSet {
            if let imageName = app?.imageName {
                photoImageView.image = UIImage(named: imageName)
            }
        }
    }

    let photoImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = true
        iv.layer.cornerRadius = 10
        iv.image = #imageLiteral(resourceName: "IMG_2545")
        iv.layer.masksToBounds = true
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()

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

        addSubview(photoImageView)
        photoImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
        photoImageView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
        photoImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
        photoImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true

    }

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


}


但是现在我遇到了一个问题:垂直滚动时,水平部分中的行会有所改变。有什么办法可以使其恢复正常工作?

swift - 创建可以使用Swift进行水平和垂直滚动的UICollectionView-LMLPHP

最佳答案

不知道地球上哪里出了什么问题,但最终我使它起作用了。干得好:

import UIKit

class FeaturedViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UISearchResultsUpdating {

    func updateSearchResults(for searchController: UISearchController) {
        print("SeachController tapped.")
    }

    let firstCellId = "cellfirstCellIdId"

    var appCategories: [AppCategory]?




    override func viewDidLoad() {
        super.viewDidLoad()
        appCategories = AppCategory.sampleAppCategories()
        collectionView?.backgroundColor = UIColor.clear
        collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: firstCellId)
        navigationItem.title = NSLocalizedString("Original", comment: "Original")
        navigationController?.navigationBar.prefersLargeTitles = true

        let searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        navigationItem.hidesSearchBarWhenScrolling = true
        self.navigationItem.searchController = searchController

    }



    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: firstCellId, for: indexPath) as! CategoryCell
        cell.appCategory = appCategories?[indexPath.item]
        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if let count = appCategories?.count {
            return count
        }
        return 0
    }


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


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





}


这是单元格:

import  UIKit


class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    var appCategory: AppCategory? {
        didSet {
            if let name = appCategory?.name {
                firstChapterLabel.text = name
            }
        }
    }

    let secondCellId = "secondCellId"


    let appsCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = UIColor.clear
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        return collectionView
    }()

    let firstChapterLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        if UIDevice.current.userInterfaceIdiom == .phone {
            label.font = UIFont.systemFont(ofSize: 14.0, weight: UIFont.Weight.medium)
        } else {
            label.font = UIFont.systemFont(ofSize: 20.0, weight: UIFont.Weight.medium)
        }
        label.textAlignment = .left
        label.textColor = UIColor.darkGray
        return label
    }()



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

        addSubview(appsCollectionView)
        appsCollectionView.dataSource = self
        appsCollectionView.delegate = self
        appsCollectionView.register(AppCell.self, forCellWithReuseIdentifier: secondCellId)

        appsCollectionView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 16).isActive = true
        appsCollectionView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -16).isActive = true
        appsCollectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50).isActive = true
        appsCollectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true

        addSubview(firstChapterLabel)
        firstChapterLabel.leftAnchor.constraint(equalTo: appsCollectionView.leftAnchor, constant: 16).isActive = true
        firstChapterLabel.rightAnchor.constraint(equalTo: appsCollectionView.rightAnchor, constant: -16).isActive = true
        firstChapterLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 24).isActive = true


    }

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

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let count = appCategory?.apps?.count {
            return count
        }
        return 0

    }

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

        let cell =  collectionView.dequeueReusableCell(withReuseIdentifier: secondCellId, for: indexPath) as! AppCell
        cell.app = appCategory?.apps?[indexPath.item]
        return cell

    }


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

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



}




class AppCell: UICollectionViewCell {

    var app: App? {
        didSet {
            if let imageName = app?.imageName {
                photoImageView.image = UIImage(named: imageName)
            }
        }
    }


    let photoImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = true
        iv.layer.cornerRadius = 9
        iv.layer.masksToBounds = true
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()



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


        addSubview(photoImageView)
        photoImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 16).isActive = true
        photoImageView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -16).isActive = true
        photoImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -36).isActive = true
        photoImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 36).isActive = true




    }



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


}


并且模型保持了问题中所描述的那样。

关于swift - 创建可以使用Swift进行水平和垂直滚动的UICollectionView,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48829647/

10-10 10:16