Safe Area Issues with ScrollView / {NS} 4



Maybe we can discuss the following issue and some workarounds for it here. I’ll also open an issue on GitHub.

I know that a list should be implemented using a ListView. This is just some sample content to demonstrate the issue.

Current Behavior

There’s a white bar at the bottom of the screen underneath the home indicator. It probably has got the exact dimensions of the safe area. This takes care of the ScrollView’s content so the home indicator won’t get in the way but it looks ugly.

There’s a workaround for this white bar: White bottom bar underneath iPhone X home indicator

I have implemented it as a toggle in this Playground. Here’s what happens if you toggle / enable margin:

The white bar goes away, but ScrollViews no longer take care of the safe area. Now of course I could add a StackLayout with no content but a padding that’s equal to the safe area bottom inset. Anyways that’s an ugly workaround that was not required before upgrading to NativeScript 4. (Also I would have to remove it everywhere once this get’s fixed…) Not to mention that the Scrolling Indicator would be incorrect.

What is interesting thought is that the ListView is working great with this marginBottom Workaround. (The Scrolling Indicator is displayed correctly too in that case. – With a small inset for the safe area at the bottom.)

Need some code to work with? Check out this Playground.

Expected Behavior

I have implemented the same kind of view natively. Here’s the native implementation which behaves as expected:

The ScrollView perfectly respects the Safe Area on the iPhone X while keeping the containers background color under the home indicator intact. No white bars / whatsoever – just works.

import UIKit

class ViewController: UIViewController {
    let labelHeight: CGFloat = 20
    let spacing: CGFloat = 16
    let count: Int = 50

    override func viewDidLoad() {
        // Do any additional setup after loading the view, typically from a nib.
        let container = UIView(frame: self.view.frame)
        let scrollView = UIScrollView(frame: self.view.frame)
        let stackView   = UIStackView()
        var contentHeight: CGFloat = 0
        container.backgroundColor = UIColor.gray
        stackView.axis = UILayoutConstraintAxis.vertical
        stackView.distribution = UIStackViewDistribution.equalSpacing
        stackView.alignment =
        stackView.spacing = spacing
        for index in 1...count {
            let text = "Label #\(index)"
            let label = UILabel()
            label.backgroundColor = UIColor.yellow
            label.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true
            label.heightAnchor.constraint(equalToConstant: labelHeight).isActive = true
            label.text = text
            label.textAlignment = .center
            contentHeight += labelHeight + spacing
        stackView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.contentSize = CGSize(width: self.view.frame.width, height: contentHeight)

    override func didReceiveMemoryWarning() {
        // Dispose of any resources that can be recreated.