我想具体知道滚动视图的偏移量何时到达页面中心。不幸的是,scrollViewDidScroll
不会对所有值进行采样。所以我不是每次经过屏幕中央时都进入if
。我怎样才能克服这个问题?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let page = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
let offsetInPage = (scrollView.contentOffset.x / scrollView.frame.size.width) - CGFloat(page)
if offsetInPage == 0.5 { // Does not called every time
toggleColors()
}
}
contentOffset
通过处理触摸手势来更新,这无法连续完成,因为它不像您在每次更改时都从触摸屏接收消息,而是系统正在检查触摸屏的状态在某个循环中。在这种情况下,它是运行循环。因此,在运行循环迭代之间可能会发生一些更改,并且应用程序不会捕获这些更改。从理论上讲,在某些情况下,差距甚至可能超过整个页面。
因此,最好检查一下现在可见的区域,并计算当该区域可见时应该应用什么颜色,而不是等待出现某个确切的contentOffset
值
根据您的代码,您似乎只想在用户滚动时切换颜色,以便所有奇数页都具有一种颜色,而所有偶数页 - 另一种颜色。如果是这样,我会这样做:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let page = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
let isOddPage = (page % 2 == 1)
let offsetInPage = (scrollView.contentOffset.x / scrollView.frame.size.width) - CGFloat(page)
if (isOddPage && offsetInPage < 0.5) || (!isOddPage && offsetInPage >= 0.5) {
switchToOddColor()
} else {
switchToEvenColor()
}
}
或类似的东西。也许您的情况更复杂,也许您不止两种颜色,但策略是相同的。
检查颜色是否尚未在switchToOddColor
中设置为所需的值也很有用,switchToEvenColor
以避免执行额外的工作。
我建议您 1) 检查一个表示页面偏移量是否大于一半的值,并且 2) 仅在值更改时才切换颜色:
var isOverHalf: Bool = true
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let page = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
let offsetInPage = (scrollView.contentOffset.x / scrollView.frame.size.width) - CGFloat(page)
let isOverHalf = offsetInPage > 0.5
If self.isOverHalf != isOverHalf {
toggleColors()
}
self.isOverHalf = isOverHalf
}
也许这是一种不需要的答案,这里也是 RxSwift 版本:
scrollView.rx.didSCroll
.map { [weak scrollView] _ in scrollView?.offsetInPage ?? 0 }
.map { $0 > 0.5 }
.distinctUntilChanged() // this line prevents toggleColors() from being called for the same values multiple times
.subscribe(onNext: { [weak self] _ in
self?.toggleColors()
})
.disposed(by: disposeBag)
extension UIScrollView {
var offsetInPage: CGFloat {
let page = contentOffset.x / frame.size.width
return page - floor(page)
}
}
由于您使用浮点数进行比较,我建议使用如下所示的范围:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let page = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
let offsetInPage = (scrollView.contentOffset.x / scrollView.frame.size.width) - CGFloat(page)
if (0.45..<0.55).contains(offsetInPage) {
print("near to center")
toggleColors()
}
}
像scrollViewDidScroll
这样的函数不能在每个浮点值上触发,因为这是不可能的!您需要像上面一样检查或尝试lowerValue
、biggerValue
捕获 2 个值。