[英]Why is the CollectionView function called twice in Swift?
I am having trouble with the function being called 2 times.我在调用函数 2 次时遇到问题。 Because of this, the value in PageView is not set properly because the index value is not correct.因此,PageView 中的值设置不正确,因为索引值不正确。 How can you control this correctly?你怎么能正确地控制它?
ViewController.swift视图控制器.swift
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var pageView: UIPageControl!
@IBOutlet var guideView: UIView!
var step : Int! = 0
var beforeStep : Int! = 0
var imageArray = [UIImage(named: "swipe1"),
UIImage(named: "swipe2"),
UIImage(named: "swipe3"),
UIImage(named: "swipe4"),
UIImage(named: "swipe5")]
override func viewDidLoad() {
super.viewDidLoad()
pageView.numberOfPages = imageArray.count
pageView.currentPage = 0
pageView.currentPageIndicatorTintColor = UIColor.color(.dacColor)
pageView.pageIndicatorTintColor = UIColor.gray
view.backgroundColor = UIColor(red: CGFloat(252.0/255.0), green: CGFloat(251.0/255.0), blue: CGFloat(245.0/255.0), alpha: CGFloat(1.0))
collectionView.backgroundColor = UIColor(red: CGFloat(252.0/255.0), green: CGFloat(251.0/255.0), blue: CGFloat(245.0/255.0), alpha: CGFloat(1.0))
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
if let vc = cell.viewWithTag(111) as? UIImageView {
vc.image = imageArray[indexPath.row]
}
if let ab = guideView.viewWithTag(222) as? UIPageControl {
ab.currentPage = indexPath.row - 1
}
return cell
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let size = collectionView.frame.size
return CGSize(width: size.width, height: size.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
problematic function part有问题的功能部分
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
if let vc = cell.viewWithTag(111) as? UIImageView {
vc.image = imageArray[indexPath.row]
}
if let ab = guideView.viewWithTag(222) as? UIPageControl {
ab.currentPage = indexPath.row - 1
}
return cell
}
CollectionView in StoryBoard StoryBoard 中的 CollectionView
View List in Storyboard在故事板中查看列表
I want the PageController to be marked to match the location of the picture.我希望将 PageController 标记为匹配图片的位置。
Has anyone solved the same problem as me?有没有人解决过和我一样的问题?
collectionView(_:cellForItemAt:)
is a collection view delegate method which tends to get called more than once, and there are a lot of factors that trigger the call like: collectionView(_:cellForItemAt:)
是一个集合视图委托方法,它往往会被多次调用,并且有很多因素会触发调用,例如:
The number of visible cells you've got, depending on the height of the collection您拥有的可见单元格的数量,取决于集合的高度
When scrolling through cells to reuse them滚动单元格以重用它们时
Or triggers to change/refresh the collection like:或触发更改/刷新集合,例如:
reloadData()
, reloadItems(at:)
or reloadSections(_:)
reloadData()
、 reloadItems(at:)
或reloadSections(_:)
Perhaps a layoutIfNeeded()
call from the view that contains this collection view.也许来自包含此集合视图的视图的layoutIfNeeded()
调用。
and more...和更多...
The point is, the function getting called more than once is pretty normal.关键是,函数被多次调用是很正常的。 Your answer probably lies in "What triggers the call?"您的答案可能在于“是什么触发了呼叫?”
EDIT :编辑:
To update your pageControl according to the index of the collection:要根据集合的索引更新您的 pageControl:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let visibleRect = CGRect(origin: yourCollectionView.contentOffset, size: yourCollectionView.bounds.size)
let midPointOfVisibleRect = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = yourCollectionView.indexPathForItem(at: midPointOfVisibleRect) {
yourPageControl.currentPage = visibleIndexPath.row
}
}
If you're using a UIPageViewController
just for the page indication, a UIPageControl
should do.如果您仅将UIPageViewController
用于页面指示,则应使用UIPageControl
。 You might also have to set yourCollectionView.isPagingEnabled = true
as that would be more appropriate for a page control.您可能还必须设置yourCollectionView.isPagingEnabled = true
因为这更适合页面控件。
In collection view go to layout and select custom:在集合视图中转到布局并选择自定义:
class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout
{
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
{
if let collectionViewBounds = self.collectionView?.bounds
{
let halfWidthOfVC = collectionViewBounds.size.width * 0.5
let proposedContentOffsetCenterX = proposedContentOffset.x + halfWidthOfVC
if let attributesForVisibleCells = self.layoutAttributesForElements(in: collectionViewBounds)
{
var candidateAttribute : UICollectionViewLayoutAttributes?
for attributes in attributesForVisibleCells
{
let candAttr : UICollectionViewLayoutAttributes? = candidateAttribute
if candAttr != nil
{
let a = attributes.center.x - proposedContentOffsetCenterX
let b = candAttr!.center.x - proposedContentOffsetCenterX
if fabs(a) < fabs(b)
{
candidateAttribute = attributes
}
}
else
{
candidateAttribute = attributes
continue
}
}
if candidateAttribute != nil
{
return CGPoint(x: candidateAttribute!.center.x - halfWidthOfVC, y: proposedContentOffset.y);
}
}
}
return CGPoint.zero
}
}
and then in delegate:然后在委托中:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
var visibleRect = CGRect()
visibleRect.origin = Collections.contentOffset
visibleRect.size = Collections.bounds.size
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
guard let indexPath = Collections.indexPathForItem(at: visiblePoint) else { return }
print(indexPath.item)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.