【问题标题】:CollectionView Not Loaded Until I Scroll?CollectionView 直到我滚动才加载?
【发布时间】:2018-03-22 18:50:34
【问题描述】:

所以我的 collectionView 有问题。目前我的设置是一个有两个部分的设置。每个部分中的数据都是从某个数据库中提取的,然后基于这些相应的部分中。

下面是我的主 homeFeedController 的代码

class HomeFeedController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    // let dropDownLauncher = DropDownLauncher()
    let dispatchGroup = DispatchGroup()
    var isFinishedPaging = false
    var userLocation: CLLocation?
    var allEvents = [Event]()
    var eventKeys = [String]()
    var featuredEvents = [Event]()
    private let cellID = "cellID"
    private let catergoryCellID = "catergoryCellID"
    var images: [String] = ["gear1","gear4","snakeman","gear4","gear1"]
        var images1: [String] = ["sage","sagemode","kyubi","Naruto_Part_III","team7"]
    var featuredEventsHeaderString = "Featured Events"
    var categories : [String] = ["Seize The Night","Seize The Day","21 & Up", "Friends Events"]

    override func viewDidLoad() {
        super.viewDidLoad()
//        navigationItem.title = "Featured Events"
        collectionView?.backgroundColor = .white
        collectionView?.showsVerticalScrollIndicator = false
        SVProgressHUD.dismiss()
        grabUserLoc()
        collectionView?.register(HomeFeedCell.self, forCellWithReuseIdentifier: cellID)
                collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: catergoryCellID)
       // reloadHomeFeed()
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.navigationController?.setNavigationBarHidden(true, animated: false)
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
//        self.view.removeFromSuperview()
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
        print("EventDetailViewController class removed from memory")
    }




    @objc func grabUserLoc(){

        LocationService.getUserLocation { (location) in
            guard let currentLocation = location else {
                return
            }
            PostService.showEvent(for: currentLocation, completion: { [unowned self](events) in
                self.allEvents = events
                print("Event count in PostService Closure:\(self.allEvents.count)")
                DispatchQueue.main.async {
                   // self.dynamoCollectionView.reloadData()
                    //self.dynamoCollectionViewTop.reloadData()
                }

            })

            PostService.showFeaturedEvent(for: currentLocation, completion: { [unowned self] (events) in

                self.featuredEvents = events
                print("Event count in Featured Events Closure is:\(self.featuredEvents.count)")
                DispatchQueue.main.async {
                    // self.dynamoCollectionView.reloadData()
                   // self.dynamoCollectionViewTop.reloadData()
                }
            }
            )
            print("Latitude: \(currentLocation.coordinate.latitude)")
            print("Longitude: \(currentLocation.coordinate.longitude)")
        }

    }

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

        if indexPath.section == 0 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! HomeFeedCell
            cell.sectionNameLabel.text = "Featured Events"
            cell.featuredEvents = featuredEvents
            return cell
        }

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: catergoryCellID, for: indexPath) as! CategoryCell
        cell.sectionNameLabel.text = categories[indexPath.item]
        print(categories[indexPath.item])
        print(indexPath.item)
        cell.categoryEvents = allEvents
        return cell

    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if section == 1{
            return 4
        }
        return 1
    }

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

        if indexPath.section == 0 {
             return CGSize(width: view.frame.width, height: 300)
        }
        return CGSize(width: view.frame.width, height: 290)

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        if section == 0 {
            return UIEdgeInsets(top: 5, left: 0, bottom: 10, right: 0)
        }
        return UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
    }

在这个家庭提要控制器中创建的单元格在每个单元格中都有 collectionViews,它们创建了某种可滚动的网格布局。此外,每个单元格都会传递一个事件,其中包含渲染大部分单元格所需的信息。我的单元格的基本布局如下。

import UIKit

class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
    private let cellID = "cellID"
    var categoryEvents: [Event]?{
        didSet{
            categoryCollectionView.reloadData()
        }
    }
    var titles: String? {
        didSet {
            guard let titles = titles else {
                return
            }
             sectionNameLabel.text = titles
        }
    }


    let sectionNameLabel : UILabel =  {
        let sectionNameLabel = UILabel()
        sectionNameLabel.font = UIFont(name:"HelveticaNeue-Bold", size: 16.0)
        return sectionNameLabel
    }()

    let categoryCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .clear
        return cv
    }()

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        guard let currentEventCount = categoryEvents?.count else{
            return 0
        }
        return currentEventCount
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! CategoryEventCell
        cell.event = categoryEvents?[indexPath.item]
        return cell
    }

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

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 14, bottom: 0, right: 14)
    }

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

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


    @objc func setupViews(){
        backgroundColor = .clear
        addSubview(categoryCollectionView)
        addSubview(sectionNameLabel)
        sectionNameLabel.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 14, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
                categoryCollectionView.anchor(top: sectionNameLabel.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
                categoryCollectionView.delegate = self
                categoryCollectionView.dataSource = self
                categoryCollectionView.showsHorizontalScrollIndicator = false
        categoryCollectionView.register(CategoryEventCell.self, forCellWithReuseIdentifier: cellID)

    }
}

这个包含 collectionView 的单元格最终将特定事件传递给一个单元格,该单元格最终获取渲染自身所需的内容。代码如下。

import UIKit
import Firebase
import FirebaseDatabase

class CategoryEventCell: BaseRoundedCardCell {

    var event: Event? {
    didSet{
        guard let currentEvent = event else {
            return
        }
        guard let url = URL(string: currentEvent.currentEventImage) else { return }
        backgroundImageView.af_setImage(withURL: url)
        eventNameLabel.text = currentEvent.currentEventName.capitalized
    }
    }

    public var backgroundImageView: CustomImageView = {
        let firstImage = CustomImageView()
        firstImage.clipsToBounds = true
        firstImage.translatesAutoresizingMaskIntoConstraints = false
        firstImage.contentMode = .scaleToFill
        firstImage.layer.cornerRadius = 15
        return firstImage
    }()

    let eventNameLabel : UILabel =  {
        let sectionNameLabel = UILabel()
        sectionNameLabel.font = UIFont(name:"HelveticaNeue-Bold", size: 14.0)
        return sectionNameLabel
    }()


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

        setupViews()
    }

    @objc func setupViews(){
        backgroundColor = .clear
       // setCellShadow()
        addSubview(backgroundImageView)
        addSubview(eventNameLabel)
        backgroundImageView.setContentCompressionResistancePriority(UILayoutPriority(600), for: .vertical)
        backgroundImageView.anchor(top: topAnchor, left: leftAnchor, bottom: eventNameLabel.topAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        eventNameLabel.anchor(top: backgroundImageView.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

    }

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

}

由于某种原因,该问题似乎与在应用程序启动时加载内容有关,但没有加载任何内容。但只要我滚动一切都开始加载。除此之外,当其他部分加载时,有一个部分甚至根本不加载任何内容。我希望所有单元格在我进入屏幕时而不是在滚动时加载它们的内容。如果这是一个新手错误,我深表歉意,但这并不是我想要的方式。也有一次用户界面实际上被锁定了。我当前的 UI 看起来像这样。任何帮助表示赞赏。这已经困扰了我好几个小时了

我知道当单元格在视图内时会加载 collectionViews,但问题是它们都不会加载,直到我向下或向上滚动,无论方向可能是什么。

【问题讨论】:

    标签: ios swift uicollectionview


    【解决方案1】:

    UICollectionView 的工作原理是,在索引路径上安装单元格仅在它在显示中时才会出现。如果单元格不在可见的集合视图中。单元格将 br dqqued 重用于另一个索引。因此,当您使用每个单元格获取数据时..cellForRowAtIndexPath 未创建所有单元格,仅创建可见单元格。

    您可以利用 Collection 视图 Prefetch 功能在数据呈现之前加载数据。

    您可以参考更多关于预取 UICollectionView 的详细信息

    https://www.captechconsulting.com/blogs/uicollectionview-prefetching-in-ios-10

    【讨论】:

    • 即使它只在视图内加载。所有这些都没有加载是主要问题
    猜你喜欢
    • 2019-10-03
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 2017-01-22
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多