【问题标题】:Creating UICollectionView which can scroll horizontally and vertically with Swift创建可以使用 Swift 水平和垂直滚动的 UICollectionView
【发布时间】:2018-07-27 12:46:48
【问题描述】:

我正在尝试创建一个可以水平和垂直滚动的 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 uicollectionview horizontal-scrolling vertical-scrolling


    【解决方案1】:

    不知道到底出了什么问题,但我终于搞定了。给你:

    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")
        }
    
    
    }
    

    模型保持原样。

    【讨论】:

      猜你喜欢
      • 2015-05-31
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      相关资源
      最近更新 更多