Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在UICollectionView滚动后获取可见项的更新IndexPath_Ios_Swift_Uiscrollview_Uicollectionview - Fatal编程技术网

Ios 在UICollectionView滚动后获取可见项的更新IndexPath

Ios 在UICollectionView滚动后获取可见项的更新IndexPath,ios,swift,uiscrollview,uicollectionview,Ios,Swift,Uiscrollview,Uicollectionview,我有一个collectionView,每天都有不同的时段供用户选择。每个项目的大小都等于collectionView本身的大小 @IBOutlet weak var periodCollectionView: UICollectionView! @IBOutlet weak var itemLabel: UILabel! let collectionValues = ["Day", "Week", "Month", "Year"] var currentVisibleItem: Int? o

我有一个collectionView,每天都有不同的时段供用户选择。每个项目的大小都等于collectionView本身的大小

@IBOutlet weak var periodCollectionView: UICollectionView!
@IBOutlet weak var itemLabel: UILabel!

let collectionValues = ["Day", "Week", "Month", "Year"]
var currentVisibleItem: Int?

override func viewDidLoad() {
    super.viewDidLoad()

}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 4
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PeriodName", for: indexPath) as? DisplayPeriodCollectionViewCell
    else {
        fatalError("Unable to cast collection view cell as DisplayPeriodCollectionViewCell")
    }

    cell.periodName.text = collectionValues[indexPath.item]

    return cell

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let height = collectionView.frame.height
    let width = collectionView.frame.width

    return CGSize(width: width, height: height)
}
我试图做的是在collectionView滚动后,获取一个信息标签来显示当前可见项的索引。她的密码是:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    let centerPoint = CGPoint(x: periodCollectionView.center.x + periodCollectionView.contentOffset.x, y: 1.0)
    print("centerPoint: \(centerPoint)")

    if let currentItemIndexPath = periodCollectionView.indexPathForItem(at: centerPoint) {
        currentVisibleItem = currentItemIndexPath.item
        print("index of current item: \(currentVisibleItem!)")
        itemLabel.text = "\(currentVisibleItem!)"
    } else {
        print("could not get index of current item...")
    }

}
我添加了print语句来检查在运行时是否正确定义了值,它们显示一切正常。问题在于,标签在滚动结束后并不总是更新其文本,而是等待新的滚动发生:

我不明白为什么会发生这种情况——在ScrollViewDiEndDecelling上设置断点表明所有代码都已执行,那么标签文本有什么问题

UPD。不更新标签文本似乎是一个模拟器问题-在设备上运行时,标签会正确更新。

试试这个

override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let currentIndex = scrollView.contentOffset.x / CGFloat((itemWidth + interitemSpacing / 2))
    print(currentIndex)
}
试试这个

override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let currentIndex = scrollView.contentOffset.x / CGFloat((itemWidth + interitemSpacing / 2))
    print(currentIndex)
}

在您的情况下,您可以使用:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
因为每个项目与集合视图的大小相同。 如果仍要使用滚动视图委托,则应在以下委托函数中编写页面计算:

func scrollViewDidEndDragging(UIScrollView, willDecelerate: Bool)

func scrollViewDidEndDecelerating(UIScrollView)

func scrollViewDidEndScrollingAnimation(UIScrollView)

在您的情况下,您可以使用:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
因为每个项目与集合视图的大小相同。 如果仍要使用滚动视图委托,则应在以下委托函数中编写页面计算:

func scrollViewDidEndDragging(UIScrollView, willDecelerate: Bool)

func scrollViewDidEndDecelerating(UIScrollView)

func scrollViewDidEndScrollingAnimation(UIScrollView)
请尝试以下代码

我在我的实际项目中使用过很多次,效果很好

请尝试以下代码

我在我的实际项目中使用过很多次,效果很好


这是一种更简洁的获取索引的方法,感谢您的提示!关于标签文本更新-似乎是模拟器的问题,检查更新到问题这是一个更紧凑的方式来获取索引,感谢提示!关于标签文本更新-似乎是模拟器问题,请检查更新到问题ScrollViewDiEndScrollingAnimation\是否工作得更好?我不会仅仅依赖于模拟器问题。这可能只是一个计时问题,而你只是在你的设备上看不到它,但它可能发生在较慢/较快的设备上。问题是每次集合视图滚动时都会执行所有代码,包括标签更新。我用断点检查了一下。但在模拟器上,标签更新由于某些原因没有显示。我在之前滚动的滚动视图中看到了更新标签的问题。我想知道是否在模拟器上还没有完成滚动动画,但在您尝试更新标签时已经在设备上完成了。你试过scrollViewDidEndScrollingAnimation吗?scrollViewDidEndScrollingAnimation根本不起作用-在控制台打印语句中也不起作用,在模拟器中也不起作用。scrollViewDidEndScrollingAnimation:效果更好吗?我不会仅仅依赖于模拟器的问题。这可能只是一个计时问题,而你只是在你的设备上看不到它,但它可能发生在较慢/较快的设备上。问题是每次集合视图滚动时都会执行所有代码,包括标签更新。我用断点检查了一下。但在模拟器上,标签更新由于某些原因没有显示。我在之前滚动的滚动视图中看到了更新标签的问题。我想知道是否在模拟器上还没有完成滚动动画,但在您尝试更新标签时已经在设备上完成了。您是否尝试了ScrollViewDiEndScrollingAnimation?ScrollViewDiEndScrollingAnimation根本不起作用-无论是在控制台打印语句中,还是在模拟器中。cellForItemAt方法的问题是,对于当前项的indexPath,它非常不可预测。当向前滚动时,它会被调用两次-对于即将到来的单元格和之后的单元格。向后滚动时,可能根本不会调用它,因为单元格仍在堆栈中。是否尝试使用func tableViewUITableView,willDisplay:UITableViewCell,forRowAt:IndexPath?实现所有三种滚动视图委托方法有助于增强gif上的箭头按钮。它们应该循环遍历集合项,但单滚动视图didendDecelling方法对它们不起作用。willDisplay会给出相同的不可预测的结果,这意味着它可能返回的不是当前单元格,而是它后面或前面的单元格,具体取决于滚动方向。对于当前索引的精确计算,最好的方法是在下面的答案中提供@DenisLitvin。cellForItemAt方法的问题是,对于当前项的indexPath,它非常不可预测。当向前滚动时,它会被调用两次-对于即将到来的单元格和之后的单元格。向后滚动时,可能根本不会调用它,因为单元格仍在堆栈中。是否尝试使用func tableViewUITableView,willDisplay:UITableViewCell,forRowAt:IndexPath?实现所有三种滚动视图委托方法有助于增强gif上的箭头按钮。它们应该遍历集合项,但是 le ScrollViewDiEndDecelling方法对它们不起作用。willDisplay会给出同样不可预测的结果,这意味着它可能返回的不是当前单元格,而是它后面或前面的单元格,具体取决于滚动方向。为了精确计算当前指数,最好的方法是在下面的答案中提供@DenisLitvin。