【问题标题】:Setting a bottom scroll indicator inset on a UIScrollView view has unexpected effect on horizontal scrollbar position在 UIScrollView 视图上设置底部滚动指示器插入对水平滚动条位置有意想不到的影响
【发布时间】:2019-11-17 00:41:27
【问题描述】:

UIScrollView 让我们设置一个scrollIndicatorInset。但是,当在带有safeAreaInset(即“缺口”)的横向 iPhone 上为此值设置底部插图时,滚动条的水平位置会意外更新。

这是 iPhone X 上的滚动视图,scrollIndicatorInset 没有变化 - 请注意,右边缘的滚动条与屏幕边缘水平齐平。

现在我添加一行代码:

scrollView.scrollIndicatorInsets.bottom = 1

滚动指示器的底部边缘按预期插入。但是滚动条现在也被水平重新定位以与安全区域对齐,而不是屏幕边缘。

这种水平插入的原因是什么,我该如何预防?

将底部滚动插图设置为 0 以外的任何值都会添加额外的边距,而将其设置回 0 则会删除它。设置任何滚动插入边缘时,同样适用。

在设置 scrollIndicatorInset 之前和之后的一些日志显示,视图、滚动视图或滚动视图内的内容视图上的 safeAreaInsetlayoutMargins 都没有变化。

问题的一个地方是在滚动视图中放置一个文本字段并调整底部插图以适应键盘。当键盘出现和关闭时,滚动条会四处跳动。

我在下面提供了一个小型视图控制器,以防您想自己尝试一下。

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let scrollView = UIScrollView()
        scrollView.backgroundColor = .white
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(scrollView)
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        let contentView = UIView()
        contentView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(contentView)
        contentView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
        contentView.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
        contentView.widthAnchor.constraint(equalToConstant: 50).isActive = true
        contentView.heightAnchor.constraint(equalToConstant: 500).isActive = true

        // this causes the issue
        scrollView.scrollIndicatorInsets.bottom = 1
    }
}

【问题讨论】:

  • 我注意到 Apple 的邮件应用程序也有类似的问题 - 在横向撰写电子邮件时,滚动条会随着键盘的显示/关闭而移入/移出。我不认为这是预期的行为,所以可能是 iOS 错误。很高兴找到解决方法。
  • 看起来更改 .scrollIndicatorInsets 会导致 UIKit 计算相对于安全区域的滚动指示器框架,即使您的滚动视图被限制在视图中。

标签: ios uiscrollview autolayout


【解决方案1】:

这是一个老问题,但作为一种解决方法,您还可以将滚动视图的右侧指示器插入设置为适当的负距离,例如父视图的右侧安全区域插入。

override func viewDidAppear(_ animated: Bool) {
    scrollView.verticalScrollIndicatorInsets.right = -self.view.safeAreaInsets.right
}

在 iOS 13 及更高版本中,我们应该使用 horizontalScrollIndicatorInsetsverticalScrollIndicatorInsets,因为 scrollIndicatorInsets 已被弃用。

这不是一个完美的解决方法,因为您会发现顶部和底部的插图也需要调整。例如,也许您正在尝试将底部插图设置为在屏幕的一半处结束,并且您对此感到满意。但在这些调整之后,顶部插图现在默认为零,因此您可能也需要调整它,否则滚动指示器将一直向上移动到设备的圆角。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-02
    • 2019-10-05
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    相关资源
    最近更新 更多