表视图内的CollectionView无法正确显示数据

问题描述 投票:0回答:1

[编辑]如果需要其他信息,我很乐意提供。

我遇到了一个至今无法弄清楚的情况。嵌入表视图内的集合视图;我使用数据字典来存储数据,总共7个部分。问题是,在重新加载数据时,它无法正确读取数据字典,并且显示的图像和部分名称不一致。

注意一点:如果我将字典限制为 4 个部分,它就可以正常工作,只有当它超过这个部分时,我才会遇到问题。

这是数据字典的副本:

var data1 = [quoteData(sectionType: "For You", quotes: ["Categories/General.png"
            ]),
             
             quoteData(sectionType: "Free Today", quotes: ["Categories/Loneliness.png", "Categories/Setting Goals.png"
            ]),
             
             quoteData(sectionType: "Hard Times", quotes: ["Categories/Death.png", "Categories/Loneliness.png"
            ]),
             
             quoteData(sectionType: "Calm Down", quotes:["Categories/Appreciation.png", "Categories/Managing Anxiety.png"
            ]),
             
             quoteData(sectionType: "Relationships", quotes:["Categories/Friendship.png"
            ]),
             
             quoteData(sectionType: "Personal Growth", quotes: ["Categories/Confidence.png", "Categories/Courage.png"
            ]),
             
             quoteData(sectionType: "Spiritual and Philosophy", quotes: ["Categories/Poetry.png"
            ]),
]

视图控制器如下:

extension CategoriesViewController: UITableViewDelegate, UITableViewDataSource {
    
    //MARK: - Methods
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 200
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return data1.count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return data1[section].sectionType
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! CategoriesTableViewCell
        cell.collectionView.tag = indexPath.section

        guard let catCell = cell as? CategoriesTableViewCell else {
            return cell
        }
        
        catCell.didSelectItemAction = { [weak self]  String in
            self!.existingCat = (self?.defaults.string(forKey: "DefaultQuotes"))!
            self?.defaultCat = String
            if self?.defaultCat != "" {
                if self?.defaultCat != "General" {
                    self?.adAlert()
                } else {
                    // update
                    self?.defaults.set(self?.defaultCat, forKey: "DefaultQuotes")
                    self?.navigationController?.popViewController(animated: true)
                }
            } else {
                self?.navigationController?.popViewController(animated: true)
            }
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        view.layer.borderWidth = 4
        view.layer.borderColor = UIColor.white.cgColor
        if section == 0 {
            view.tintColor = .clear
        } else {
            // view.tintColor = .colorFromHex("a5d7fa")
            view.tintColor = .colorFromHex("ffffff")
        }
        let header = view as! UITableViewHeaderFooterView
        header.textLabel?.textColor = UIColor.black
        header.textLabel?.font = UIFont.preferredFont(forTextStyle: .title3)

    }
    
    func adAlert() {
        let showAlert = UIAlertController(title: "Unlock Quotes", message: nil, preferredStyle: .alert)
        //let image = UIImage(named: "MIsc/PaintBrushColor")
        
        showAlert.addAction(UIAlertAction(title: "Watch Video", style: .default, handler: { action in
            // Show Ad & update
            self.showAd()
            if self.defaultCat == self.existingCat {
                self.defaults.set(false, forKey: "resetIndex")
            } else {
                self.defaults.set(true, forKey: "resetIndex")
            }
            // update the Default quotes data area and Highlight box
            self.defaults.set(String(self.defaultCat), forKey: "DefaultQuotes")
            // pop view controller
            self.navigationController?.popViewController(animated: true)
        }))
        showAlert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { action in
        }))
        self.present(showAlert, animated: true, completion: nil)
    }

TableViewCell代码: 类 CategoryTableViewCell: UITableViewCell {

// Outlets
@IBOutlet weak var collectionView: UICollectionView!

//Constants
let defaults = UserDefaults.standard

// Variables
var resetIndex: Bool = false
var myCat: String = ""
var didSelectItemAction: ((String) -> Void)?


//Methods
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    collectionView.delegate = self
    collectionView.dataSource = self
    myCat = defaults.string(forKey: "DefaultQuotes")!
    resetIndex = defaults.bool(forKey: "ResetIndex")
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

扩展类别TableViewCell:UICollectionViewDelegate,UICollectionViewDataSource {

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath)
    let lblQuote = cell.viewWithTag(80) as? UILabel
    let dougie = data1[collectionView.tag].quotes[indexPath.row]
    // Get range 4 places from the start, and 6 from the end.
    let r = dougie.index(dougie.startIndex, offsetBy: 11)..<dougie.index(dougie.endIndex, offsetBy: -4)
    // Access the string by the range.
    let subString = dougie[r]
    myCat = String(subString)
    didSelectItemAction?(myCat)
    //collectionView.reloadData()
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return data1[collectionView.tag].quotes.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath) as! CategoriesCollectionViewCell
    let Defaults = UserDefaults.standard
    let defQuote = Defaults.string(forKey: "DefaultQuotes")
    cell.images.image = UIImage(named: data1[collectionView.tag].quotes[indexPath.row])
    let myLbl = cell.viewWithTag(80) as? UILabel
    let myIcon = cell.viewWithTag(83) as? UIImageView
    myIcon?.image = UIImage(named: "bed.double.circle")
    let padlock = cell.viewWithTag(81) as? UIImageView
    let dougie = data1[collectionView.tag].quotes[indexPath.row]
    // Get range 4 places from the start, and 6 from the end.
    let r = dougie.index(dougie.startIndex, offsetBy: 11)..<dougie.index(dougie.endIndex, offsetBy: -4)
    // Access the string by the range.
    let substring = dougie[r]
    myLbl?.text? = String(substring)
    if myLbl?.text == defQuote {
        // we are going to set the border
        cell.images?.layer.borderWidth = 2.5
        cell.images?.layer.borderColor = UIColor.red.cgColor
        cell.images?.clipsToBounds = true
    } else {
        cell.images?.layer.borderWidth = 0.0
        cell.images?.layer.borderColor = UIColor.clear.cgColor
        cell.images?.clipsToBounds = false
    }
    print(data1[collectionView.tag].sectionType)
    let doggie = getImg(Inb: String(substring))
    if doggie == "" {
        let strIcon = "CatIcons/" + String(substring) + ".png"
        myIcon?.image = UIImage(named: strIcon)
    } else {
        myIcon?.image = UIImage(systemName: doggie)
    }
    if myLbl?.text == "General" || data1[collectionView.tag].sectionType == "Free Today" {
        padlock?.isHidden = true
    } else {
        padlock?.isHidden = false
    }
    return cell
}

func getImg(Inb: String) -> String {
    var retVal: String
    switch Inb {
    case "General":
        retVal = "rainbow"
    case "Hope":
        retVal = "sunrise"
    case "Sleep":
        retVal = "bed.double.circle"
    case "Mindfulness":
        retVal = "brain.head.profile"
    case "Enjoy the Moment":
        retVal = "figure.2"
    case "Calm":
        retVal = "figure.yoga"
    default:
        retVal = ""
    }
    return retVal
}

}

uicollectionview tableview
1个回答
0
投票

代码中的一个可能的问题是由于表格视图和嵌入集合视图之间的单元格重用和数据同步的管理引起的,通过正确设置标签来同步集合视图的数据,并在

cellForRowAt
中重新加载集合视图数据表视图数据源的方法

类似这样的:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! CategoriesTableViewCell
        /* 
        Set the collection view tag to match the section index; 
        the tag will later be used to ensure 
        the correct data is loaded for each collection view. 
        */
        cell.collectionView.tag = indexPath.section
        cell.collectionView.reloadData() 
    
        // Continue your code
    }

然后就可以使用标签了

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // Use collectionView.tag to access the correct section of your data model.
    return data1[collectionView.tag].quotes.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath) as! CategoriesCollectionViewCell
    // Configure the cell using data1[collectionView.tag] to get the correct data for this collection view
    let quote = data1[collectionView.tag].quotes[indexPath.row]
    // Your code continues here
}

这远非最佳解决方案,但应该可行。

© www.soinside.com 2019 - 2024. All rights reserved.