在UIScrollView视图上设置底部滚动指示器插图会对水平滚动条位置产生意外影响

时间:2019-07-07 02:45:32

标签: ios uiscrollview autolayout

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

这是iPhone X上的滚动视图,未更改scrollIndicatorInset-请注意,右侧的滚动条与屏幕边缘水平齐平。

现在我添加一行代码:

scrollView.scrollIndicatorInsets.bottom = 1

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

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

将底部滚动插入设置为除0之外的任何值会添加额外的边距,将其重新设置为0会将其删除。设置任何滚动插入边缘时,同样适用。

在设置scrollIndicatorInset之前和之后的某些日志记录都不会在视图,滚动视图或滚动视图中的内容视图上对safeAreaInsetlayoutMargins进行任何更改。 / p>

这是一个问题,当在滚动视图中放置文本字段并调整底部插图以容纳键盘时。出现并关闭键盘时,滚动条会跳来跳去。

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

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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