修复自适应大小单元格的 scrollToRow/ItemAtIndexPath:
方法
UITableView 和 UICollectionView 中的自适应大小单元格非常棒,但它们会导致 scrollToRowAtIndexPath:
和 scrollToItemAtIndexPath:
方法无法可靠地工作。
这个小型库为 UITableView 和 UICollectionView 添加了 reallyScrollTo...
变体,它通过使用 CADisplayLink 自行执行滚动,并在需要时进行调整,从而可靠地滚动到正确的位置。
public func reallyScrollToRow(at indexPath: IndexPath,
at scrollPosition: UITableView.ScrollPosition,
insets: UIEdgeInsets = .zero,
animated: Bool,
completion: ((UITableView, _ hasCompleted: Bool) -> Void)? = nil)
func reallyScrollToItem(at indexPath: IndexPath,
at scrollPosition: UICollectionView.ScrollPosition,
insets: UIEdgeInsets = .zero,
animated: Bool,
completion: ((UICollectionView, _ hasCompleted: Bool) -> Void)? = nil)
您可以指定在滚动时应考虑的额外内边距。例如,如果您希望将一行滚动到顶部下方 10 个点的位置,可以使用 at: .top, insets: UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
有一个可选的 completionHandler,当滚动完成时将被调用,并带有一个 hasCompleted
标志,以指示我们是否完全滚动到指定的偏移量,或者是否被中断。
此外,检查 scrollView.scroller.isScrolling
也可以查看当前是否正在进行滚动动画。
实际的滚动和确定滚动到的位置是分开的,因此可以通过在协议中实现单个方法来轻松扩展
protocol ScrollOffsetProviderProtocol {
func targetScrollOffset(witStartOffset startOffset: CGPoint) -> CGPoint?
}
然后调用
class MyScrollOffsetProvider: ScrollOffsetProviderProtocol {
func targetScrollOffset(witStartOffset startOffset: CGPoint) -> CGPoint? {
// calculate actual position, gets called on every animation frame.
// It's fine to return different positions on each invocation,
// as long as it eventually stabilizes (otherwise we'll scroll
// forever).
return ...;
}
}
let scrollView = UIScrollView()
let provider = MyScrollOffsetProvider()
scrollView.startScrolling(with: provider, animated: true)
只需动态返回要滚动到的偏移量,该库就会使其发生。