scrollview - 内容视图 - 1)图像,2)选项卡,3)堆栈视图
以上是我的故事板安排。选项卡实际上是集合视图。在选项卡下方,有堆栈视图(也在内容视图中)。当我单击每个选项卡时,我会在didSelect上发送所选选项卡的索引。它将调用具有此流程的refreshData函数:将删除堆栈视图中的当前子视图(使用vc.mainStack.subviews.forEach({$ 0.removeFromSuperview()}))并将根据索引重新加载另一个子视图选定的标签。图像的位置将保持不变,位于页面顶部。但是,每次单击选项卡时,屏幕将始终滚动到顶部。如何保持滚动位置(在我单击另一个选项卡之前),以便当我单击新选项卡时,它将保持在相同的滚动位置?
self.yContentOffset = scrollView.contentOffset.y
已经在scrollViewDidScroll和。中添加了上面的代码
vc.scrollView.contentOffset.y = self.yContentOffset
删除堆栈中的所有子视图后添加上面的代码,然后我调用新数据(对于子视图)。还尝试在调用新子视图后添加代码,但两者都不起作用。有谁知道如何做到这一点的逻辑?
听起来问题是UI在您删除当前子视图的点和添加新子视图之间被“刷新”。所以你的mainStack
变得非常短,导致内容视图不够高,不需要滚动,你的滚动视图相应调整自己。
您可以选择等待删除子视图,直到获得新的子视图,然后删除/添加相同的func,或者使用明确的“占位符”视图替换子视图。
第二个选项可能如下所示:
func replaceViewsWithPlaceholderView() -> Void {
// get an array of the current views in the stack
let viewsToRemove = mainStack.arrangedSubviews
// create a clear view
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .clear
// needs a width
v.widthAnchor.constraint(equalToConstant: 1).isActive = true
// constrain the height of the "place holder" view to the current height of the stack view
v.heightAnchor.constraint(equalToConstant: mainStack.frame.height).isActive = true
// add the "place holder" view to the stack
mainStack.addArrangedSubview(v)
// remove the views that were in the stack
viewsToRemove.forEach {
$0.removeFromSuperview()
}
}
然后在您的func中添加基于所选选项卡的新子视图,首先:
// remove the "place holder" view
mainStack.arrangedSubviews.forEach {
$0.removeFromSuperview()
}
接下来(可能是一个.forEach
循环)将新的子视图添加到main.Stack
。
当然,如果你滚动了所以你的“标签”位于滚动视图的顶部,而“标签B”没有足够的子视图来要求滚动,滚动视图将再次调整 - 但仅限于内容视图的底部位于滚动视图的底部。