xmartlabs / Eureka

Elegant iOS form builder in Swift
https://eurekacommunity.github.io
MIT License
11.78k stars 1.33k forks source link

TextAreaRow input content covered by keyboard #1938

Open D-Mx opened 4 years ago

D-Mx commented 4 years ago

Hello,

I have a problem where in a TextAreaRow if you add a large text the content goes under the keyboard. I want the tableview to show the content like in the Apple Notes App. I'm trying to scroll the tableview on the onChange event but not even a hardcoded space scrolls the table.

textAreaRow = TextAreaRow(){row in
    row.textAreaHeight = TextAreaHeight.dynamic(initialTextViewHeight: 34)
    row.placeholder = "..."
}.onChange { [weak self] row in
            guard let self = self else { return }
            print("onChange")

            //none works to scroll table
            self.tableView?.scrollRectToVisible(.zero, animated: true)
            self.tableView?.setContentOffset(.zero, animated: true)
            self.tableView?.scrollIndicatorInsets = .zero 

            //only one that scroll but I need more precision
            self.tableView?.scrollToRow(at: index!, at: .bottom, animated: true)
}

XukaK

Eureka 5.0.0

D-Mx commented 4 years ago

I found out that by doing .onChange { self.view.layoutIfNeeded() } alone automatically scrolls to the caret but not for new lines, is not until I write again that the the table scrolls

mats-claassen commented 4 years ago

Did you try scrolling the row to the .middle or .top of the screen?

tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
D-Mx commented 4 years ago

yes, but with the keyboard showing that doesn't always make the cursor/caret visible if you are at the bottom of a long text

tallot13 commented 4 years ago

in my cases problem in ios 12, ios 13 no error

tallot13 commented 4 years ago

.onChange { self.view.layoutIfNeeded() } works for me (new line and caret)

funkenstrahlen commented 4 years ago

@D-Mx I can confirm this issue. I also see this!

tyler-nguyen commented 4 years ago

I found a workaround for this.

First, save the keyboard-will-show-notification and the text area row height.

var detailRow: TextAreaRow?
var keyboardWillShowNotification: Notification?
var previousDetailRowHeight: CGFloat = 0

override func keyboardWillShow(_ notification: Notification) {
  super.keyboardWillShow(notification)
  keyboardWillShowNotification = notification
}

override func keyboardWillHide(_ notification: Notification) {
  super.keyboardWillHide(notification)
  keyboardWillShowNotification = nil
}

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  previousDetailRowHeight = detailRow!.cell.textView.frame.size.height
}

Then you can manually call keyboardWillShow again in the text area row onChange to scroll the text field to visible when it gets bigger.

.onChange({ [unowned self] (row) in
  guard let keyboardWillShowNotification = self.keyboardWillShowNotification else { return }

  let rowHeight = row.cell.textView.frame.size.height
  if rowHeight > self.previousDetailRowHeight {
    // to scroll cell to visible, to prevent keyboard from hiding texts
    self.keyboardWillShow(keyboardWillShowNotification)
  }
  self.previousDetailRowHeight = rowHeight
})