How to push key value into UITextView from custom keyboard in iOS - ios

I am building a virtual keyboard for a UITextView. All works well, I can display the keyboard and remove the keyboard as well as display the keystrokes. I am using the "stringByReplacingCharactersInRange: withString" method to place the new keystroke into the text view. This works but since it is replacing the string each time, the entry point goes to the end of the string. This all makes sense, but is not very usable. I can fix this by doing checks in my code but there might be something better...
So my question is this; Is there a way to push the new key to the UITextView directly without modifying the UITextView's text property's string manually? The manual states that I will have to manage the target/action myself, but I was wondering if I've missed an action to call. It seems that the Apple Default keyboard must have a slick way of punching the keystroke into the object without the obvious number of checks that I will have to do to make the typing smooth.
Any help will be greatly appreciated.
Thanks,
Rob

Well, I didn't get any responses. So I figured out a way to do it so it is reasonable and simple. It's a matter of tracking the selected range. So when I wish to Backspace I use this technique.
NSRange currentRange = self.myTextView.selectedRange;
if (currentRange.length == 0) {
currentRange.location--;
currentRange.length++;
}
self.myTextView.text = [self.myTextView.text stringByReplacingCharactersInRange:currentRange withString:[NSString string]];
currentRange.length = 0;
self.myTextView.selectedRange = currentRange;
If I need to type a character this works.
NSRange currentRange = self.myTextView.selectedRange;
self.myTextView.text = [self.myTextView.text stringByReplacingCharactersInRange:currentRange withString:someCharacter];
currentRange.location++;
currentRange.length = 0;
self.myTextView.selectedRange = currentRange;
If anyone has a better way, I'd like to hear it.
Thanks,
Rob

Related

Why does InsertText from UITextInput breaks keyboard suggestions?

So we recently had an issue with our Keyboard extension showing wrong suggestions in the accompanying app. We found out that the text returned from context (super.textDocumentProxy.documentContextBeforeInput) was all wrong and since its a build in apple component something must go wrong with text insertion. We had following implementation for inserting text:
if (replaceRange.length > 0) {
[self.textView.textStorage replaceCharactersInRange:replaceRange withString:selectedWord];
[textView setSelectedRange:NSMakeRange(newLocation, 0)]; //Place cursor after inserted word
} else {
[self.textView insertText:selectedWord];
}
Would return something like:
There. . .
While the real text would be something like:
There it was. It was a little test. Test of everything.
The issue was found to be with insertText apparently it will properly insert text but the Keyboard context will not be able to read the inserted text. Now the fix was simply to use the replaceCharactersInRange for both insertions (meaning no if / else clause):
[self.textView.textStorage replaceCharactersInRange:replaceRange withString:selectedWord];
[textView setSelectedRange:NSMakeRange(newLocation, 0)]; //Place cursor after inserted word
This solved the issue and has made us conclude that insertText doesn't work as intended. Note that this will only be an issue if suggestions are to be used in the text field.

UITextView link detect bug with iOS 8.3

I put into a non editable UITextView only one URL as string in order to make a link that work great until iOS8.3, set is :
myTextView.text = aLink;
First set is ok nice and link work well when touch, but another set will failed, text
is ok with the new url text, link is well detected with blue color but touch will always responds with first url as if UITextView be not uptaded.
Does I have to set another thing into UITextView ?
One solution:
Just after setting new string (with a link) I remove detection property:
self.myTextView.dataDetectorTypes = UIDataDetectorTypeNone;
and trig after 0.1 second a new setting as:
self.myTextView.dataDetectorTypes = UIDataDetectorTypeLink;
Works fine.
I found a slightly alternative way that seems to fix it in my case. It avoids using a timer so the fix seems instant.
self.textviewText.dataDetectorTypes = UIDataDetectorTypes.init(rawValue: 0)
self.textviewText.text = newstring
self.textviewText.dataDetectorTypes = .link

iOS Instagram Tags Text Layout? How Is It Done?

I've always been curious how instagram gets it's tags to layout fluidly and wanted to know what goes behind this functionality? To me, it seems like they're using UIButton's and just calculating placement of the buttons line by line? Is that right? Or is there a simpler method of doing it without having to manual calculate the placement of each tag line by line / or side by side given that multiple tag's width's fit together?
Or, are they using NSAttributedStrings?
Any ideas?
Here's an example of the layout I'm referring to.
Well, I'm currently working on NSAttributedString and UITextView to get all this working, and my current code can do it. So I'm going to explain a possible version of doing this.
Here are the tips and big steps, with iOS7:
NSAttributedString, in iOS7 has a new attribute : NSLinkAttributeName. You can add it to your NSAttributedString, and with a detection method (combining: how to make #key and #key clickable in IOS7 and Get word from tap in UITextView) you can manage it. That's for the general way of doing it. For previous version, you'll have to do a little more of work, but keeping this general idea.
But since, it only for hashtags, since you can detect the world behind the tap, you can do this: Detect what word has been tapped (see previous links), detect if this word has an hashtag, and if yes, you can do whatever action you want. You can play with a NSRegularExpression to know where are the hashtags, and know when to "color" them.
Here is a simplified way to do it using UITextView and NSAttributedString:
Use regular expressions to get character ranges for links.
Add link styling to the matched ranges.
Add custom attribute to range that references tap action to execute.
On touch, if index of character is inside a matched range, change the link formatting to highlight it and run the associated tap action.
How to get index of character at location in iOS7:
- (NSUInteger) getCharIndexAt: (CGPoint) location
{
NSLayoutManager *layoutManager = self.layoutManager;
NSUInteger characterIndex = NSNotFound;
characterIndex = [layoutManager characterIndexForPoint:location inTextContainer:self.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
return characterIndex;
}
Also check out WWDC 2013 intro to TextKit Demo
ios7 text utilities

How to implement search function to UITextView?

I have more than 40 views with their own respective UITexView. I want to implement a search function that allows the user to search across the UITextViews. Actually, I do not even know how to implement search function for 1 UITextView. Therefore I do not know if it is possible at all.
I have searched the web and looked for it here but did not find what I looked for.
I appreciate your advice.
This is a pretty easy (may I say obvious?) task. Just think a bit about it. What does searching in a text view mean? Well, it means getting its text and see if a particular string (the one which is searched for) is the substring of the text, and if so, where it is inside. Assuming you use a UISearchBar to hold the text to be searched for:
NSString *subs = searchBar.text;
NSString *wholeText = textView.text;
NSRange r = [wholeText rangeOfString:subs];
if (r.location == NSNotFound)
{
// The term to be searched couldn't be found...
}
else
{
// The string to be searched for is in the text view, r.location contains where exactly it is.
}
You can search for text in TextView like this:
[TextView.text rangeOfString:]
There's no built in controller for searching UITextView, you have to implement this functionality by yourself with above function.

Disable the kanji auto-complete (henkan) for Japanese keyboards in iOS?

I am using a UITextField and have turned off the normal auto correction features but I need Japanese keyboards to not show the kanji auto-complete views that appear above the keyboard when typing. I am trying to quiz the user and so it is important that this feature is disabled.
Any ideas?
Probably this is a long time for the answer, however for the completion purpose, you can override shouldChangeCharactersInRange method and return NO from this method.
I had accidentally done this, and my auto-completion had stopped. Seems that my problem was a solution to someone else :)
You should be able to hide the predicted words by setting the autocorrectionType like this:
self.textField.autocorrectionType = UITextAutocorrectionTypeNo;
This can also be done in storyboard -> UITextField --> Text Input Traits --> Correction = No

Resources