为啥我们需要 visibleCells 函数(UICollectionView)
Posted
技术标签:
【中文标题】为啥我们需要 visibleCells 函数(UICollectionView)【英文标题】:Why do we need visibleCells function (UICollectionView)为什么我们需要 visibleCells 函数(UICollectionView) 【发布时间】:2018-03-19 15:37:37 【问题描述】:目前我有由 4 个单元格组成的集合视图。这是一个水平collectionView,每个显示一个单元格,所以每次有一个单元格应该显示自己。当我旋转我的设备时,每个屏幕模式下这个单元格也处于打开状态。每次我对我的 collectionView 说显示可见单元格时,它都会显示不同的数组。 (从纵向到横向 2 个阵列单元格,从横向到纵向阵列甚至 3 个阵列单元格)。如果这个 visibleCells 数组每次都不同,为什么我们需要它?以及为什么每次都不一样(我的意思是从波特到霍尔,反之亦然) 这是我的代码
override func viewDidLoad()
super.viewDidLoad()
view.addSubview(collectionView)
view.addSubview(pageControl)
view.addSubview(skipButton)
view.addSubview(nextButton)
print( view.constraints)
nextButton.anchorWithConstantsToTop(nil, left: nil, bottom: nil, right:
view.rightAnchor, topConstant: 16, leftConstant: 0, bottomConstant: 0, rightConstant: 0)
nextButtonTopAnchor = nextButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 16)
nextButtonTopAnchor?.isActive = true
nextButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
nextButton.widthAnchor.constraint(equalToConstant: 60).isActive = true
skipButton.anchorWithConstantsToTop(nil, left: view.leftAnchor, bottom: nil, right: nil, topConstant: 16, leftConstant: 0, bottomConstant: 0, rightConstant: 0)
skipButtonTopAnchor = skipButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 16)
skipButtonTopAnchor?.isActive = true
skipButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
skipButton.widthAnchor.constraint(equalToConstant: 60).isActive = true
pageControl.anchorWithConstantsToTop(nil, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, topConstant: 0, leftConstant: 28, bottomConstant: 0, rightConstant: 28)
print("\(pageControlConstant) L")
pageControl.heightAnchor.constraint(equalToConstant: 40).isActive = true
if UIDevice.current.orientation.isPortrait || (UIDevice.current.orientation.isFlat && UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ) pageControlBottomAnchor = pageControl.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor, constant: 0)
else if UIInterfaceOrientationIsPortrait(self.interfaceOrientation) == false
pageControlBottomAnchor = pageControl.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor, constant: 5)
pageControlBottomAnchor?.isActive = true
collectionView.anchorToTop(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
registerCells()
func scrollViewDidScroll(_ scrollView: UIScrollView)
view.endEditing(true)
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)
if pageControl.currentPage != pages.count
if UIDevice.current.orientation.isLandscape || (UIDevice.current.orientation.isFlat && UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
self.nextButtonTopAnchor?.constant = 0
self.skipButtonTopAnchor?.constant = 0
self.pageControlBottomAnchor?.constant = 5
self.tabBarController?.tabBar.isHidden = true
else
self.nextButtonTopAnchor?.constant = 16
self.skipButtonTopAnchor?.constant = 16
self.pageControlBottomAnchor?.constant = 0
self.tabBarController?.tabBar.isHidden = false
if pageControl.currentPage == pages.count
var mySpecialCell = collectionView.cellForItem(at:IndexPath(item: pages.count, section: 0)) as! LoginCell
if (UIDevice.current.orientation.isLandscape || (UIDevice.current.orientation.isFlat && UIInterfaceOrientationIsLandscape(UIInterfaceOrientation.landscapeLeft)) )
mySpecialCell.someShit = "landSpace"
else
mySpecialCell.someShit = "portrait"
collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()
collectionView.reloadData()
DispatchQueue.main.async
let indexPath = IndexPath(item: self.pageControl.currentPage, section: 0)
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
if (UIDevice.current.orientation.isLandscape || (UIDevice.current.orientation.isFlat && UIInterfaceOrientationIsLandscape(UIInterfaceOrientation.landscapeLeft)) )
else
self.collectionView.reloadData()
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
let pageNumber = Int(targetContentOffset.pointee.x / view.frame.width)
print( view.constraints)
pageControl.currentPage = Int(pageNumber)
if pageNumber == pages.count
nextButtonTopAnchor?.constant = -40
skipButtonTopAnchor?.constant = -40
pageControlBottomAnchor?.constant = 50
print(pageControlBottomAnchor)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations:
self.view.layoutIfNeeded()
, completion: nil)
else
if UIDevice.current.orientation.isLandscape || (UIDevice.current.orientation.isFlat && UIInterfaceOrientationIsLandscape(self.interfaceOrientation) )
pageControlBottomAnchor?.constant = 5
self.nextButtonTopAnchor?.constant = 0
self.skipButtonTopAnchor?.constant = 0
else if (UIDevice.current.orientation.isFlat && UIInterfaceOrientationIsPortrait(self.interfaceOrientation) || !UIDevice.current.orientation.isLandscape )
self.nextButtonTopAnchor?.constant = 16
self.skipButtonTopAnchor?.constant = 16
pageControlBottomAnchor?.constant = 0
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations:
self.view.layoutIfNeeded()
, completion: nil)
fileprivate func moveControlConstraintsOffScreen()
pageControlBottomAnchor?.constant = 150
pageControlBottomAnchor?.isActive = true
fileprivate func registerCells()
collectionView.register(PageCell.self, forCellWithReuseIdentifier: cellId)
collectionView.register(LoginCell.self, forCellWithReuseIdentifier: loginCellId)
collectionView.register(LoginCellLandscape.self, forCellWithReuseIdentifier: loginCellLandscapeId)
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
print("I will display \(cell) for \(indexPath)")
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
print("I did end displaying \(cell) for \(indexPath)")
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return pages.count + 1
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let loginCell = collectionView.dequeueReusableCell(withReuseIdentifier: loginCellId, for: indexPath)
return loginCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! PageCell
let page = pages[indexPath.item]
cell.page = page
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: view.frame.width, height: view.frame.height)
【问题讨论】:
【参考方案1】:将问题解读为问为什么UICollectionView
有visibleCells
函数...
听起来你不需要它。它不是在每个应用程序中都有用。但有时确实如此。这是一个例子:
假设您的单元格显示表示随时间变化的事件的数据——也许是时间轴中的 Twitter 帖子。并且假设您的 UI 包含一个显示每个事件发生时间的字段——“20 秒前”、“3 米前”等。为了保持这些时间准确,您可以设置一个计时器以定期更新值。定时器触发时应该发生什么?
你可以告诉表视图重新加载它的数据。这将是有效的,但它比必要的工作要多得多。您不需要重新加载整个单元格,只需更新单元格中的一个字段。但是哪些细胞?只有那些可见的。因此,询问集合视图哪些单元格可见,并更新这些单元格中的时间字段。
询问设备旋转时哪些单元格可见可能没有用,因为当您观察到时,可见单元格会发生变化。不过,在我没想到的情况下,有人可能会用到它。
【讨论】:
以上是关于为啥我们需要 visibleCells 函数(UICollectionView)的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们需要 Lync SDK 控件,如果它们不能在 UI 抑制模式下使用?
UITableView.visibleCells.contains(JDHeaderTableViewCell()) 总是返回 false