Adding background image to the selected in an UITextView - ios

I would like to add a background image for the selected text in the UITextView, not for the whole view, as I marked in the below picture.
How can I add a background image for the selected text?
Or, how can I add one small image before and another one after the
selected without making the other text move back or forward?

UITextInput protocol should provide everything you need.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInput_Protocol/Reference/Reference.html
Specifically:
selectedTextRange
firstRectForRange
firstRectForRange: which will tell you the rectangle covering a range of characters. If the range of characters spans multiple lines, you have to call it repeatedly. The first time it will give you the first rect and tell you what range that covers. Then, you adjust the range you're asking about to be the remaining characters you're interested in and repeat.

Related

UITextView scrollRangeToVisible make range visible appear at the top

I am currently using UITextView. When I use scrollRangeToVisible it works but it brings the range to the bottom of the screen. How can I bring this range to the top of the screen. TLDR: UITextview method scrollRangeToVisible brings the characters of interest to bottom of view. I want it to come to top of view. How can I do this? Thank you
One approach is to:
find the bounding box of the range you want at the top
if it's below the current top line, add the height of the text view
then call .scrollRectToVisible()
You also need some error and bounds checking. I put together an extension you can try out if you wish: https://gist.github.com/DonMag/19daac863553c51725a56f0bc3296076

Adding UITextField inline UILabel (Fill in the blanks)

I am trying to achieve something like this for iOS in Objective C.
The fill in the blanks(UITextField) should be inline, and should be able to have its own inputType.
Also, each View is a type of cell.contentView of a UITableViewCell.
My current approach is to find the length of string and also calculate the wrapping content length to the next line. Calculate the x's and y's for UITextField and add another UILabel after the UTextField
Is there any other approach other than this?
As EmilioPelaez says, this is not exactly an answer to your question, but a suggestion:
You can use a collection view with an horizontal flow for each "sequence" (i.e. UILabel-UItextfield-etc...)
That collection view has 2 kind of cell:
One with a uilabel with the number of line set to "1"
and the correct layout to fit the cell.
Another with a uitextfield and the correct layout
Coupled with:
My current approach is to find the length of string and also calculate the wrapping content length to the next line.
You may be able to easily adjust the width of the different cells, hide a uitextfield (if needed) and display a more dynamic "sequence" (if needed)
This is not exactly an answer to your question, instead it's a suggestion for a different interaction.
I think that instead of using inline textFields, you could use a UILabel with an attributed string, and in where the textFields would be, you add a different character with a different color that you can tap (For example, this character ✚).
When tapped, you can show an overlay with a text input, and once that input is completed, you update the label with the text (still tappable, and with a different color).
I think this answer might also be relevant: Detecting taps on attributed text in a UITextView in iOS
I think your solution of separating the UILabels and calculating their required positions is a good one for versions lower than iOS9, but if you can count on iOS, UIStackView can dramatically simplify the process for you. You can read more about the process in this tutorial:
UIStackView Tutorial
Good luck!

Making some parts of a `UITextField` un-selectable

I have a UITextField that will represent an integer number with a fraction (numerator and denominator). As an example: "27 3/16". I want to make the denominator "/16" at the end both un-editable and also un-selectable.
I can use the delegate method textField:shouldChangeCharactersInRange:replacementString: to prevent the "/16?" from being edited with an approach a bit like this.
Is there some way that I can also prevent the "/16" from being selectable at all? So, the caret can't be moved in to it, and the selection marque can't be made around it.
If this isn't possible, is there a hook so that once the user finishes placing their selection, I can update the selection and move the caret to just before this piece of the text.
Thanks.
You can have a UILabel and UITextField constrained via autolayout next to each other, the UILabel containing the denumerator and the UITextField the numerator.
Here is an answered question for how to do that: Using Auto Layout to have UILabel and UITextField next to each other (the essence is, you need to adjust the content hugging priority of the UITextField to make it always as wide as the contained text.
If your text field gets too small to be tapped, you can apply the code of this answer to a UITextView and make the tappable area of your view bigger: UIButton: Making the hit area larger than the default hit area (but better use method swizzling than overriding a method in a category like in the answer! Or a subclass.)

How to extract sub-string from UILabel based on finger pressed location?

I have a UILabel which contains text.
Once I press on this UILabel, I want to extract one word from the location where my finger pressed.
I've searched a bit on internet, but have no clue about how to implement it.
Does anyone here know how to do it?
Thanks in advance.
Once I press on this UILabel, I want to extract one word from the
location where my finger pressed.
That's not something that's going to be easy to do with UILabel. UILabel is meant to be a simple way to put static text on the screen; it doesn't provide features that would let you determine the frames of individual words.
You'll probably be better off creating your own view for this. You'll want to dig into Core Text to lay out and draw the text. Core Text is a lot more complicated than just using a simple UILabel, but it gives you the information and control you'll need to determine where each word is drawn on the screen. Your view can use that information to map touches to words.
The easiest way is to just make each individual word a separate label, so that all you have to do is add a UITapGestureRecognizer to the label and grab the text from it when it's touched.
If you want to do it with one label, though, here's some pseudocode of a way that could work:
Add a UITapGestureRecognizer to the label. When touched, get the location of the touch.
Use NSString's - (CGSize)sizeWithFont:(UIFont *)font method to get the size of the label's entire string (let's call this stringSize).
Compare stringSize.width to the width of your label to figure out where the text begins (if your label is center or right aligned, this might not be at the label's starting X coordinates). ie. startingX = label.width - stringSize.width / 2.
Now use NSString's - (NSArray *)componentsSeparatedByString:(NSString *)separator method to separate the string in your label into each word, with the space character as the delimiter. Let's store this into an array called wordsAr.
Create a variable, currentXPos, and initialize it to startingX.
Now create a for loop that goes through each word in wordsAr, calculates the size of that word using - (CGSize)sizeWithFont:(UIFont *)font, and adds it to currentXPos. When currentXPos >= the x location of your touch value, you've found the word that you tapped on.
You can use TTTAttributedLabel in the following link: https://github.com/mattt/TTTAttributedLabel
Define your clickable texts as Links for the Label, then you'll get exactly what you need.

how to implement the autoresizing UITextView vertically?

First look at the screenshot:
second press the return button, the screenshot for your reference:
after four times click
return
button, the height of text field will not be higher any more.
now here is the question: how can I implement the function of textfield? and what about the background Image behind the text Field , should auto resize too? if there are any solution, let me know! thanks very much----
Make it UITextView not a text field, track the text changes at shouldChangeTextInRange of the textView delegate.
In this method calculate the number of lines (textView.contentSize.height/textView.font.lineHeight), compare it with the previous value to decide whether you need to proceed or just return. If the number of lines is changed, check whether the textView is already displaying the maximum number of lines (that must be 3 on the image) and based on the results you will change the textView, it's superview and a button frames (you can also make it animated easily) and probably scroll the text to the change region with scrollRangeToVisible.

Resources