Ios 设置集合视图的初始滚动位置
我尝试过许多解决办法,但都不管用。问题很简单-如何在Ios 设置集合视图的初始滚动位置,ios,swift,uicollectionview,Ios,Swift,Uicollectionview,我尝试过许多解决办法,但都不管用。问题很简单-如何在viewDidLoad期间向下滚动,viewwillbeen或viewdidbeen而不产生视觉(跳转)效果 我现在所拥有的: public override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() if (!self.layoutFlag) { if let lastCell: IndexPath = self.lastCell
viewDidLoad
期间向下滚动,viewwillbeen
或viewdidbeen
而不产生视觉(跳转)效果
我现在所拥有的:
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if (!self.layoutFlag) {
if let lastCell: IndexPath = self.lastCellIndexPath {
self.collectionView?.scrollToItem(at: lastCell, at: UICollectionViewScrollPosition.bottom, animated: true)
self.layoutFlag = true
}
}
}
在测试项目中选中,在
视图中工作将出现。我添加了3个屏幕,第一个是干净的,第二个包含collectionView,最后一个是空的
第二个屏幕的实现如下(ViewWillView触发UIScrollView扩展方法并滚动内容):
这里有一个用于滚动内容的扩展名
:
extension UIScrollView {
func scrollToTop(animated: Bool) {
setContentOffset(CGPoint(x: 0, y: -contentInset.top),
animated: animated)
}
func scrollToBottom(animated: Bool) {
setContentOffset(CGPoint(x: 0, y: CGFloat.greatestFiniteMagnitude),
animated: animated)
}
}
尝试创建一个新的干净的项目并使用它。将滚动到索引路径调用添加到视图显示(:)
方法,并将动画的参数设置为false
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if !self.layoutFlag {
if let lastCell: IndexPath = self.lastCellIndexPath {
self.collectionView?.scrollToItem(at: lastCell, at: UICollectionViewScrollPosition.bottom, animated: false)
self.layoutFlag = true
}
}
}
在向用户显示视图之前,集合视图应该滚动到底部,这样就不会“跳转”。我发现只有一种方法可以设置初始滚动位置:
在中调用我的滚动功能
这看起来不是正确的答案,但它是有效的
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
}
}
只需在异步块中包装scrollToItem
。它工作完美,无视觉过渡,易于应用
我只能猜测它是如何工作的。在viewDidLoad中同步滚动集合视图将不起作用,因为它尚未布局。异步块中的提交滚动将此操作添加到下一个runloop任务中,当执行下一个runloop时,也就是将绘制ui的时候,滚动将立即执行,并显示在同一帧中
以上所有的都只是猜测,任何人都知道我很乐意学习。你试过将动画设置为假?@JuicyFruit,是的,视觉效果更差。好吧,你可以将收藏视图设置为隐藏,将alpha设置为0,然后在scrolltoitem
显示之后,设置其alpha
的动画不确定,但检查它是否有效。@danilabagroff好吧,如果它在测试项目(不是游乐场)中有效,那么您已经有了一个应该有效的解决方案。你可以慢慢地从你原来的项目中排除一些功能,调查是什么导致了这个小故障,并找出如何修复它。这很好,它可以工作,但对我来说太粗糙了,所以我创建了一个子类。看看这里的其他答案,我知道反对票来自哪里,但这对我很有用。
var isScrolled = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !isScrolled && levelCollectionView.visibleCells.count > 0 {
isScrolled = true
// scroll
}
}
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
}
}