1

I want to obtain the location of the present caret in UITextView as CGRect, but there seems to be no information. Even the official documentation, I can't imagine how to utilize this method and find the explanation. Now I could know the way of getting the offset in the UITextView, not CGRect. But, I really want to know the CGRect.

Any comments should be highly appreciated. Thanks.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Kazuya Tomita
  • 667
  • 14
  • 34
  • It is quite unclear what you are asking. The function in the documentation you linked to already returns a `CGRect`? – Oskar Apr 26 '17 at 12:36
  • Sorry, my explanation was not enough, but what is the argument `for position: UITextPosition` like? What should I pass over this method? In the sense, there is no measurements. And Now I am experimenting it. However, do you know it? – Kazuya Tomita Apr 26 '17 at 12:39
  • http://stackoverflow.com/questions/9126709/create-uitextrange-from-nsrange ? Is that what you are looking for? The link possible between `UITextPosition` and `UITextView`? – Larme Apr 26 '17 at 12:54
  • it is written in Objective-C, I just want to know the way in Swift3. Even swift 2 seems to be different with Swift 3. – Kazuya Tomita Apr 26 '17 at 12:56
  • So, although there are many similar questions here, but my question is new one in the sense. – Kazuya Tomita Apr 26 '17 at 12:56
  • See http://stackoverflow.com/a/43321695/1457385 – shallowThought Apr 26 '17 at 13:14
  • still can't understand the argument, so I can't use this method properly. Could you tell me the meaning of the argument? – Kazuya Tomita Apr 26 '17 at 13:22
  • Tiny additional information: In the official document, they say the argument is an object that identifies a location in a document. But to me, how do we fix the location by using the `position`? Could you give me any explanation? – Kazuya Tomita Apr 26 '17 at 13:25

2 Answers2

1

Try this:

extension UITextView {
    var caret: CGRect? {
        guard let selectedTextRange = self.selectedTextRange else { return nil }
        return self.caretRect(for: selectedTextRange.end)
    }
}

and use it like this:

let textView: UITextView = ...
if let caret = textView.caret {
    // Do your thing here.
} else {
    // Caret is undefined. 
}

By the way, you were on the right track :-) The above solution is based on the UITextInput method you just mentioned:

func caretRect(for position: UITextPosition) -> CGRect

Return a rectangle used to draw the caret at a given insertion point.

The UITextPosition parameter represents a position in a text container; in other words, it is an index into the backing string in a text-displaying view.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
  • Thanks. My problem I tried to solve was already solved, but I am still unclear. In your the last sentence, what is exactly `a text container`? And I can't also understand the meaning of the `the backing string`. Could you explain? – Kazuya Tomita Apr 27 '17 at 02:30
  • @KazuyaTomita The **backing string** stores the actual text being displayed by the text view, *independently* of how the text is currently being shown in the screen (eg, view width, view height, # of lines, etc). The `UITextPosition` provides a position/index into this backing string. Ex: If the text view becomes wider, the text layout will probably change using fewer lines, *but* a given `UITextPosition` index shoild remaing the same. – Paulo Mattos Apr 27 '17 at 03:19
  • What do you mean by index? Is it like an array? How do you assign those indexes toward the backing string you explained? – Kazuya Tomita Apr 27 '17 at 11:47
  • @KazuyaTomita Yes, just like array indexes. Maybe [this answer](http://stackoverflow.com/a/34923547/819340) will help further your understanding. – Paulo Mattos Apr 27 '17 at 17:20
-2
//rect is an object of CGRect
var rect = TextView.frame
Samy Nagy
  • 190
  • 1
  • 6