2

I have written a functionscrollToVisible() to scroll text in UItextview because some part of text is covered by the keyboard, or the cursor isn't in visible. But UItextview can scroll the text automatically when the cursor is not in the whole view but not visible, it can still be covered by keyboard by automatically scroll.The UItextview's auto scroll can interrupt my scrollToVisible(). Thus, can I ban the UItexview to scroll automatically? Or another way to solve "keyboard cover" problem?

My scrollToVisible() function

func scrollToVisible()
{
    let cursortop = self.EditArea.convert(self.EditArea.caretRect(for: (self.EditArea.selectedTextRange?.start)!).origin, to: self.view)
    var cursorbottom = cursortop
    cursorbottom.y += self.EditArea.caretRect(for: (self.EditArea.selectedTextRange?.start)!).height
    let bottom = UIScreen.main.bounds.size.height - self.EditArea.textContainerInset.bottom
    var contentOffset = self.EditArea.contentOffset
    if cursortop.y <= 85
    {
        contentOffset.y = contentOffset.y - 85 + cursortop.y
        self.EditArea.setContentOffset(contentOffset, animated: true)
    }
    else if cursorbottom.y >= bottom
    {
        contentOffset.y = contentOffset.y - bottom + cursorbottom.y
        self.EditArea.setContentOffset(contentOffset, animated: true)
    }
}

PS:this EditArea is the textview

cloxnu
  • 187
  • 1
  • 13
  • Your question is still unclear. Do you mean that when keyboard comes up, it covers a part of your `TextView` and you want to move it up to make whoe `TextView` visible? – Umair Aamir Jan 18 '18 at 16:20
  • @UmairAamir yes, I have set the textcontaininset so that its text can scroll to the bottom of its texts, so my problem is when the cursor is under keyboard or another invisible way, it can appear in visible if input a letter. And now I have make a function to scroll it to visible, but is conflict with textview's auto scroll. Its auto scroll can scroll text in visible but can not scroll to solve "keyboard discovery " problem – cloxnu Jan 18 '18 at 17:19
  • Can you please share the code of your `scrollToVisible()` method? – Umair Aamir Jan 18 '18 at 17:44
  • Or can you post a gif or video which explain your problem? – Umair Aamir Jan 18 '18 at 17:46
  • @UmairAamir OK,I have updated my question – cloxnu Jan 19 '18 at 03:38

2 Answers2

2

I have a similar problem: when you open the keyboard, the text view is not adjusted and the cursor hides behind the keyboard (or as you say "covers" the cursor). So if I hit enter to start a new line, it also doesn't visibly auto scroll (actually it does, but it's behind the keyboard). I found a solution, which works perfectly for me on this website: https://www.hackingwithswift.com/example-code/uikit/how-to-adjust-a-uiscrollview-to-fit-the-keyboard

Solution extracted from above website using swift 4:

Subscribe for the events when the keyboard appears and disappears in your viewDidLoad() function:

// For avoiding that the text cursor disappears behind the keyboard, adjust the text for it
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: .UIKeyboardWillHide, object: nil)
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: .UIKeyboardWillChangeFrame, object: nil)

Adjust the textview using this function, add it anywhere in your class:

// Adjusts the textView, so that the text cursor does not disappear behind the keyboard
@objc func adjustForKeyboard(notification: Notification) {
    let userInfo = notification.userInfo!

    let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)

    if notification.name == Notification.Name.UIKeyboardWillHide {
        textView.contentInset = UIEdgeInsets.zero
    } else {
        textView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height, right: 0)
    }

    textView.scrollIndicatorInsets = textView.contentInset

    let selectedRange = textView.selectedRange
    textView.scrollRangeToVisible(selectedRange)
}
Eduard
  • 176
  • 2
  • 10
  • I have used textview's scrollRangeToVisible, this function can scroll to visible only if I input a enter (but not a word).emmmm... I am not sure , so could you tell me how to use this function and the affect of this function? thank you very much! – cloxnu Jan 19 '18 at 03:51
  • I think the problem is not scrolling to visible, but that the keyboard covers up the text below it. If you have a text view, which spans across the entire screen and you start editing the text, the keyboard pops up and hides whatever text is behind it. For me, it scrolls automatically to the visible part when I type anything without using any functions. Just the keyboard was hiding it. Is it different for you? – Eduard Jan 19 '18 at 08:57
  • Oh how to use it: add the observers in the `viewDidLoad` method and the function `adjustForKeyboard` anywhere in the class. – Eduard Jan 19 '18 at 13:31
  • Yes, my problem is what you say: It can scroll automatically but the text is still hidden by the keyboard.And I have written a function to scroll it to visible (not be hidden by keyboard) , but the main problem is when I type a letter,it can scroll automatically (not my function) if my cursor is out of the whole screen, and then I type the second letter,it can scroll as my function to visible (not hidden by keyboard). So, this is why I want to ban the text view to scroll automatically. – cloxnu Jan 19 '18 at 15:36
  • Not sure if I got you right. Did you try the above solution? If I implement this, it behaves just as it ought to be. The textview scrolls automatically where you type. If I hit enter for example, it auto-scrolls down for me. The function above adapts the contentInsets, so that the scrolling works properly as desired. If the solution above is not working, let me know how to reproduce it, maybe I can help. – Eduard Jan 22 '18 at 09:26
  • Your solution has helped me with one of the other problems, it's also a important problem, with your UIKeyboardWillChangeFrame solution. Thanks! – cloxnu Jan 24 '18 at 16:24
  • Your solution has helped me with one of the other problems, it's also a important problem, with your UIKeyboardWillChangeFrame solution. Thanks! – cloxnu Jan 24 '18 at 16:25
0

Here is my solution, where you need not worry to handle any textfield/textview in the app by writing just one line of code in app delegate

If you are using pods, the you can add "IQKeyboardManager" pods by just adding the following pods

pod 'IQKeyboardManagerSwift'

and add this line in didFinishLaunchingWithOptions in app delegate

  IQKeyboardManager.sharedManager().enable = true
Sucharu Hasija
  • 1,096
  • 11
  • 23