[编辑]如果需要其他信息,我很乐意提供。
我遇到了一个至今无法弄清楚的情况。嵌入表视图内的集合视图;我使用数据字典来存储数据,总共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
}
}
代码中的一个可能的问题是由于表格视图和嵌入集合视图之间的单元格重用和数据同步的管理引起的,通过正确设置标签来同步集合视图的数据,并在
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
}
这远非最佳解决方案,但应该可行。