【问题标题】:Keep ScrollView position when clicking a tab inside (which refresh data inside)单击内部选项卡时保持 ScrollView 位置(刷新内部数据)
【发布时间】:2019-02-19 09:34:20
【问题描述】:

scrollview - 内容视图 - 1) 图像,2) 选项卡,3) 堆栈视图

以上是我的故事板安排。 标签实际上是集合视图。标签下方是堆栈视图 (也在内容视图内)。当我单击每个选项卡时,我会在 didSelect 处发送所选选项卡的索引。它将调用具有此流程的 refreshData 函数:堆栈视图中的 当前子视图 将被删除(使用 vc.mainStack .subviews.forEach({ $0.removeFromSuperview() })) 并将根据所选标签的索引重新加载另一个子视图。 图像的位置将保持不变,位于页面顶部。但是,每次我单击选项卡时,屏幕总是会滚动到顶部。如何保持滚动位置(在单击另一个选项卡之前),以便当我单击新选项卡时,它将保持在相同的滚动位置?

self.yContentOffset = scrollView.contentOffset.y

已经在scrollViewDidScroll里面添加了上面的代码

vc.scrollView.contentOffset.y = self.yContentOffset

在删除堆栈中的所有子视图后添加上面的代码,然后我调用新数据(用于子视图)。还尝试在调用新的子视图后添加代码,但两者都不起作用。有谁知道如何做到这一点的逻辑?

【问题讨论】:

  • 您需要提供更多信息...当您说 "tabs" 时,您是什么意思?那些只是排列成看起来像标签的按钮吗?您是否正在删除堆栈视图的当前.arrangedSubviews 并同时添加新的?或者,因为你说 "then i call the new data(for subviews)" 你的意思是你正在调用一个单独的操作来检索数据并且 then 添加新的子视图?
  • 嗨@DonMag,很抱歉缺少信息。我只是编辑我的问题。希望你能帮我解决这个问题。

标签: ios swift uiscrollview scrollview


【解决方案1】:

听起来问题在于,在您删除当前子视图和添加新子视图之间,UI 正在“刷新”。所以你的mainStack 变得很短,导致内容视图不够高而需要滚动,你的滚动视图会相应地调整自己。

您的选择是等待删除子视图,直到您拥有新的子视图,然后删除/添加相同的功能,或者用清晰的“占位符”视图替换子视图。

第二个选项可能如下所示:

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()
    }

}

然后在基于所选标签添加新子视图的函数中,首先:

    // remove the "place holder" view
    mainStack.arrangedSubviews.forEach {
        $0.removeFromSuperview()
    }

随后(可能是.forEach 循环)将新的子视图添加到main.Stack。

当然,如果您已经滚动,因此您的“标签”位于滚动视图的顶部,并且“标签 B”没有足够的子视图需要滚动,滚动视图将再次调整 - 但仅限于内容视图底部位于滚动视图底部的点。

【讨论】:

  • 非常感谢您的帮助。我根据我的需要安排了您的代码并且它有效! :)
猜你喜欢
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 2012-11-17
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多