未在 reloadData() 上调用 UICollectionView numberOfItemsInSection - Swift Xcode
UICollectionView numberOfItemsInSection not being called on reloadData() - Swift Xcode
我有两个视图控制器——SecondTestViewController 和 SecondContentViewController。 SecondContentViewController 是 SecondTestViewController 中的 浮动面板 。 SecondTestViewController 有一个 UITableView,SecondContentViewController 有一个 UICollectionView。
SecondContentViewController:
override func viewDidLoad() {
super.viewDidLoad()
// let layout = UICollectionViewFlowLayout()
// layout.scrollDirection = .vertical
myCollectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout())
guard let myCollectionView = myCollectionView else {
return
}
myCollectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
myCollectionView.delegate = self
myCollectionView.dataSource = self
myCollectionView.backgroundColor = .white
myCollectionView.translatesAutoresizingMaskIntoConstraints = false
myCollectionView.allowsSelection = true
myCollectionView.isSpringLoaded = true
view.backgroundColor = .white
view.addSubview(myCollectionView)
NSLayoutConstraint.activate([
myCollectionView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
myCollectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
myCollectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
myCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
}
private func collectionViewLayout() -> UICollectionViewLayout {
let layout = UICollectionViewFlowLayout()
let cellWidthHeightConstant: CGFloat = UIScreen.main.bounds.width * 0.2
layout.sectionInset = UIEdgeInsets(top: 50,
left: 10,
bottom: 0,
right: 10)
layout.scrollDirection = .vertical
layout.minimumInteritemSpacing = 0
layout.itemSize = CGSize(width: cellWidthHeightConstant, height: cellWidthHeightConstant)
return layout
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return contentData.count
print("numberOfItemsInSection activated")
print("numberOfItemsInSection = \(reviewDataController?.tableViewReviewData.count ?? 100)")
return reviewDataController?.tableViewReviewData.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print("cellForItemAt activated")
let cell = myCollectionView?.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
// cell.data = self.contentData[indexPath.item]
cell.data = self.reviewDataController.tableViewReviewData[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width / 5, height: collectionView.frame.height / 10)
}
func updateTheCollectionView() {
print("updateCollectionView activated")
print("reviewData count = \(reviewDataController.tableViewReviewData.count)")
myCollectionView?.reloadData()
}
当点击 SecondTestViewController 的 tableView 中的单元格时,它会拍照,传递数据,然后调用 SecondContentViewController 的 updateTheCollectionView() 函数。
在拍摄照片并完成各种其他任务(如更新变量等)后,在 SecondTestViewController 中调用此函数。
func passDataToContentVC() {
let contentVC = SecondContentViewController()
contentVC.reviewDataController = self.reviewDataController
contentVC.updateTheCollectionView()
}
如您所见,reloadData 应该在此函数内部调用。它现在应该用新照片更新视图。出于某种原因,就像 reloadData 从未被调用过,因为 numberOfItemsInSection 和 cellForItemsAt 都没有被第二次激活。
出了什么问题?打印语句显示正在传递数据(它们在拍摄照片后显示更新的数量)。视图只是没有更新新数据,因为没有调用两个 collectionView 函数。
编辑:
这是浮动面板代码。
fpc = FloatingPanelController()
fpc.delegate = self
guard let contentVC = storyboard?.instantiateViewController(identifier: "fpc_secondContent") as? SecondContentViewController else {
return
}
fpc.isRemovalInteractionEnabled = false
fpc.set(contentViewController: contentVC)
fpc.addPanel(toParent: self)
它基本上在 SecondTestViewController 的 viewDidLoad 内部。
有关其工作原理的更多信息:Visit this github
就 didSelectRowAt 函数而言,这里显示的代码太多了。 reviewDataController 是由结构数组组成的依赖注入。基本上所有发生的事情都是当一个单元格被点击时,它会拉起相机并允许用户拍照,然后它将照片存储在 reviewDataController 内部的数组中以及数组组成的结构中的一些其他属性.重要的部分是它应该将此数据传递给浮动面板,然后更新显示刚刚拍摄的照片的 collectionView。
好像
let contentVC = SecondContentViewController() // this is a new instance
contentVC.reviewDataController = self.reviewDataController
contentVC.updateTheCollectionView()
您创建了一个实例并将其添加到 SecondTestViewController
但 passDataToContentVC
有另一个新实例,因此显示的实例没有更新
因为您正在将数据从 SecondTestViewController
传递到 SecondContentViewController
,这是向前的而不是向后的,所以您不需要委托或任何东西。
相反,您需要做的就是保留对 SecondContentViewController
的引用。尝试这样的事情:
class SecondTestViewController {
var secondContentReference: SecondContentViewController? /// keep a reference here
override func viewDidLoad() {
super.viewDidLoad()
let fpc = FloatingPanelController()
fpc.delegate = self
guard let contentVC = storyboard?.instantiateViewController(identifier: "fpc_secondContent") as? SecondContentViewController else {
return
}
fpc.isRemovalInteractionEnabled = false
fpc.set(contentViewController: contentVC)
fpc.addPanel(toParent: self)
self.secondContentReference = contentVC /// assign contentVC to the reference
}
}
secondContentReference
保留对您的 SecondContentViewController
的引用。现在,在 passDataToContentVC
中使用它而不是使用 let contentVC = SecondContentViewController()
.
创建新实例
替换
func passDataToContentVC() {
let contentVC = SecondContentViewController()
contentVC.reviewDataController = self.reviewDataController
contentVC.updateTheCollectionView()
}
...与
func passDataToContentVC() {
secondContentReference?.reviewDataController = self.reviewDataController
secondContentReference?.updateTheCollectionView()
}
我有两个视图控制器——SecondTestViewController 和 SecondContentViewController。 SecondContentViewController 是 SecondTestViewController 中的 浮动面板 。 SecondTestViewController 有一个 UITableView,SecondContentViewController 有一个 UICollectionView。
SecondContentViewController:
override func viewDidLoad() {
super.viewDidLoad()
// let layout = UICollectionViewFlowLayout()
// layout.scrollDirection = .vertical
myCollectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout())
guard let myCollectionView = myCollectionView else {
return
}
myCollectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
myCollectionView.delegate = self
myCollectionView.dataSource = self
myCollectionView.backgroundColor = .white
myCollectionView.translatesAutoresizingMaskIntoConstraints = false
myCollectionView.allowsSelection = true
myCollectionView.isSpringLoaded = true
view.backgroundColor = .white
view.addSubview(myCollectionView)
NSLayoutConstraint.activate([
myCollectionView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
myCollectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
myCollectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
myCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
}
private func collectionViewLayout() -> UICollectionViewLayout {
let layout = UICollectionViewFlowLayout()
let cellWidthHeightConstant: CGFloat = UIScreen.main.bounds.width * 0.2
layout.sectionInset = UIEdgeInsets(top: 50,
left: 10,
bottom: 0,
right: 10)
layout.scrollDirection = .vertical
layout.minimumInteritemSpacing = 0
layout.itemSize = CGSize(width: cellWidthHeightConstant, height: cellWidthHeightConstant)
return layout
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return contentData.count
print("numberOfItemsInSection activated")
print("numberOfItemsInSection = \(reviewDataController?.tableViewReviewData.count ?? 100)")
return reviewDataController?.tableViewReviewData.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print("cellForItemAt activated")
let cell = myCollectionView?.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
// cell.data = self.contentData[indexPath.item]
cell.data = self.reviewDataController.tableViewReviewData[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width / 5, height: collectionView.frame.height / 10)
}
func updateTheCollectionView() {
print("updateCollectionView activated")
print("reviewData count = \(reviewDataController.tableViewReviewData.count)")
myCollectionView?.reloadData()
}
当点击 SecondTestViewController 的 tableView 中的单元格时,它会拍照,传递数据,然后调用 SecondContentViewController 的 updateTheCollectionView() 函数。
在拍摄照片并完成各种其他任务(如更新变量等)后,在 SecondTestViewController 中调用此函数。
func passDataToContentVC() {
let contentVC = SecondContentViewController()
contentVC.reviewDataController = self.reviewDataController
contentVC.updateTheCollectionView()
}
如您所见,reloadData 应该在此函数内部调用。它现在应该用新照片更新视图。出于某种原因,就像 reloadData 从未被调用过,因为 numberOfItemsInSection 和 cellForItemsAt 都没有被第二次激活。
出了什么问题?打印语句显示正在传递数据(它们在拍摄照片后显示更新的数量)。视图只是没有更新新数据,因为没有调用两个 collectionView 函数。
编辑: 这是浮动面板代码。
fpc = FloatingPanelController()
fpc.delegate = self
guard let contentVC = storyboard?.instantiateViewController(identifier: "fpc_secondContent") as? SecondContentViewController else {
return
}
fpc.isRemovalInteractionEnabled = false
fpc.set(contentViewController: contentVC)
fpc.addPanel(toParent: self)
它基本上在 SecondTestViewController 的 viewDidLoad 内部。
有关其工作原理的更多信息:Visit this github
就 didSelectRowAt 函数而言,这里显示的代码太多了。 reviewDataController 是由结构数组组成的依赖注入。基本上所有发生的事情都是当一个单元格被点击时,它会拉起相机并允许用户拍照,然后它将照片存储在 reviewDataController 内部的数组中以及数组组成的结构中的一些其他属性.重要的部分是它应该将此数据传递给浮动面板,然后更新显示刚刚拍摄的照片的 collectionView。
好像
let contentVC = SecondContentViewController() // this is a new instance
contentVC.reviewDataController = self.reviewDataController
contentVC.updateTheCollectionView()
您创建了一个实例并将其添加到 SecondTestViewController
但 passDataToContentVC
有另一个新实例,因此显示的实例没有更新
因为您正在将数据从 SecondTestViewController
传递到 SecondContentViewController
,这是向前的而不是向后的,所以您不需要委托或任何东西。
相反,您需要做的就是保留对 SecondContentViewController
的引用。尝试这样的事情:
class SecondTestViewController {
var secondContentReference: SecondContentViewController? /// keep a reference here
override func viewDidLoad() {
super.viewDidLoad()
let fpc = FloatingPanelController()
fpc.delegate = self
guard let contentVC = storyboard?.instantiateViewController(identifier: "fpc_secondContent") as? SecondContentViewController else {
return
}
fpc.isRemovalInteractionEnabled = false
fpc.set(contentViewController: contentVC)
fpc.addPanel(toParent: self)
self.secondContentReference = contentVC /// assign contentVC to the reference
}
}
secondContentReference
保留对您的 SecondContentViewController
的引用。现在,在 passDataToContentVC
中使用它而不是使用 let contentVC = SecondContentViewController()
.
替换
func passDataToContentVC() {
let contentVC = SecondContentViewController()
contentVC.reviewDataController = self.reviewDataController
contentVC.updateTheCollectionView()
}
...与
func passDataToContentVC() {
secondContentReference?.reviewDataController = self.reviewDataController
secondContentReference?.updateTheCollectionView()
}