6

当使用大标题并点击状态栏以滚动到UIScrollViewUITableView(可能也UICollectionView没有测试过)的顶部时,它总是有点过头了。

我已经启用了刷新TableView,当点击状态栏时,它会像这样显示并保持这种状态,直到我点击屏幕。

在此处输入图像描述

我有ScrollView另一个ViewController,如果我点击那里的状态栏,它也会滚动有点太远,使导航栏太高。当我点击某个地方或滚动一点点时,这也会恢复正常。

普通的: 在此处输入图像描述

在我点击状态栏后: 在此处输入图像描述

这也仅在我激活大标题时才会发生,使用普通标题一切正常。

任何想法如何解决这一问题?

如何重新创建:

  1. UIViewController使用导航控制器和内部创建一个新项目TableView
  2. 将导航控制器设置为更喜欢大标题。关闭半透明。设置标题UIViewController
  3. 设置约束TableView以固定到边缘ViewController
  4. TableView在中创建出口ViewController
  5. 实现委托并设置行数,例如 100
  6. 启动应用程序
  7. 向下滚动,使大标题变为普通标题
  8. 点击状态栏,tableView滚动到顶部

现在标题不在应有的位置,如果您现在向上或向下滚动一点点,它就会恢复到正常位置。

ViewController代码:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self
    }

}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for: indexPath)

        return cell
    }

}
4

5 回答 5

10

好的,所以我找到了问题发生的原因,但不知道如何在那个确切的情况下解决它。

如果您使用大标题和导航栏半透明设置为关闭的 UITableViewController,则会出现问题。当您重新打开半透明时,问题就消失了。

如果您在普通 UIViewController 中使用 TableView,则总是会出现问题。

编辑

如果您使用的是半透明导航栏,那么设置“extendedLayoutIncludesOpaqueBars = true”可以解决问题!

类似问题:iOS 11 Glitchy 效果中的 UIRefreshControl()

于 2018-06-01T09:02:40.120 回答
3

我遇到了同样的问题。我在 UINavigationController 中嵌入了 UIViewController 中的 collectionview。Collectionview 对安全区域有前导、尾随、顶部、底部约束。

要解决此问题,您需要:

  1. 将collectionview的top约束改为supervises(非安全区)
  2. 在 viewDidLoad 方法中设置 extendedLayoutIncludesOpaqueBars = true
于 2020-05-07T11:31:02.677 回答
1

经过数小时的测试,我找到了一个适用于 UIViewController 的解决方案。

在带有 UITableView 的 UIViewController 中,您应该:

  • 在 viewDidLoad 中设置 extendedLayoutIncludesOpaqueBars = true
  • 在情节提要中将 tableView 顶部约束到常量 = 0 的超级视图顶部(当导航栏为半透明时,tableView 将位于导航栏和状态栏下)

之后,如果您点击状态栏,tableview 会停在正确的位置。

在此处输入图像描述

于 2018-11-17T11:37:57.620 回答
1

在您的 ViewController 中声明一个 Bool 类型的 var didBeginScrollToTop。将控制器分配为滚动视图的委托。然后

func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
    didBeginScrollToTop = true
    return true
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard didBeginScrollToTop, scrollToTopGestureTargetView?.contentOffset.y ?? 0 < -25 else { return }

    scrollToTopGestureTargetView?.setContentOffset(.zero, animated: true)
}

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    didBeginScrollToTop = false
}

这样做是在弹跳时调整您的内容偏移量。该标志用于捕获 scrollToTop 手势并在滚动时重置。您也可以在设置 .zero 偏移后将其关闭。如果你有子 VC 的实现,在覆盖这 3 个委托方法时不要忘记调用 super。现在我的第一个方法是跟踪内容offSet 何时< 0,但在某些设备上它没有扩展导航项,而且魔法-25 似乎适用于所有模拟器。您可以将此方法与返回导航栏大小并替换它的实现相结合,但据我所知,没有一种简单的方法可以如此轻松地获取导航栏框架/边界。

请注意,您可能还必须处理这个:奇怪的速度更喜欢大标题

于 2019-08-09T15:27:44.037 回答
-1

在滚动到顶部后,我已经通过将 contentOffset 设置为 0 来修复它。

func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
    return true
}

func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = 0.0
}
于 2019-04-05T08:46:32.227 回答