Search code examples
iosswiftuiviewuitextviewquartz-core

UITextView returns inaccurate origin before text is inserted


The title pretty much tells it all. I would like to add a line right above a UITextView:

  override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    // will be implemented once bug is fixed, but for now is commented out to demonstrate error
    // if topLine == nil || bottomLine == nil {
        addBorders()
    // }
}

func addBorders() {

    let px:CGFloat = 1 / UIScreen.main.scale

    topLine = CAShapeLayer()
    topLine.backgroundColor = UIColor.blue.cgColor
    let barWidth = view.frame.size.width
    topLine.frame = CGRect(x: 0, y: 0, width: barWidth, height: px)
    topLine.frame = CGRect(x: BUFFER, y: questionTextView.frame.origin.y - BUFFER, width: barWidth, height: px)

    view.layer.addSublayer(topLine)

    // ... rest of code ...
}

For some strange reason while the UITextView is empty, the result of questionTextView.frame.origin.y is incorrect, and returns a bit down into the UITextView frame, as seen below:

img1

However, the moment text is actually entered, the origin returns the expected value, viewWillLayoutSubviews is called again, and a new line with the correct orientation is drawn, as seen below:

img2

How can I get this correct origin before any text is entered? I left space above the text view specifically for this purpose, as seen below:

img3


Solution

  • I ended up using a workaround, and created the line by adding the height of the status bar to the navigation bar then adding a buffer to that.