首页 > 解决方案 > 在 UIScrollView 视图上设置底部滚动指示器对水平滚动条位置有意想不到的影响

问题描述

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

这是 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
    }
}

标签: iosuiscrollviewautolayout

解决方案


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

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

在 iOS 13 及更高版本中,我们应该使用已弃用的horizontalScrollIndicatorInsets和。verticalScrollIndicatorInsetsscrollIndicatorInsets

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


推荐阅读