Making some parts of a `UITextField` un-selectable - ios

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.)

Related

Make multiline UILabel wrap a button

I am using storyboard to design my UIView. But I've stuck at the task: I have a multiline UILabel, UIView and UIButton. I want to make UILabel to wrap my button - the fist line of the text has a trailing constraint to UIButton another one to it's super view. And if my UILabel has no text I got a view at the bottom of label and I need to make this view trailing constraint to UIButton but if I got a free space - to it's superview.
Screenshot example:
I want to jump second line word after 'pyat' . Sorry for my poor english, hope that picture could help to explain my question.
Is it possible to make it directly in IB?
Perhaps instead of using UILabel you can try UITextView by using its textView.textContainer.exclusionPaths property to define a button container area to exclude.
Have a look at the sample code with a reported issue for selected and editable case.
As I remember you must limit the app deployment target minimum to 7 or later if using this property.
Hope that helps!
What you want to do is not supported out of the box and will take a lot of work because it will require subclassing UILabel and overriding drawRect.
An easy solution is to set attributed text on the label and use that to format the specific word to look like a button. UILabel attributed text supports hyperlink like behavior.

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!

How to resize UITextField as user types in Swift

I'm trying to write a messaging application in Swift on IOS8. Essentially I'm trying to mimic what the texting app in IOS does when you reach the edge of the textfield--the height of the textfield increases, and a new line is made. Right now when I type, the words just scroll to the side. How can I prevent the side scrolling and instead resize the textfield?
I would definitely use UITextView combined with its textViewDidChange: delegate method. You can track when the inside text changes and update your textView width (or height) accordingly by measuring its content size from constraints you specify.
You can also reimplement drawRect: to add your rounded borders or customize properties of its layer (like cornerRadius).
Placeholder can be also implemented by tracking text changes (whether by delegate methods or notifications).
I agree this isn't optimal, but at least you still have options to mimic UITextField behaviors.

"Manually" handling text and cursor position of UITextView breaks when there are multiple lines

I have a narrow UITextView (about 1 line in height) to which I only add text programmatically, setting the text property of it as I click buttons. I also handle the cursor position manually, setting the selectedRange as the text changes. All works great as long as I have only one line of text.
When I have two or more lines of text and try to insert text at the first line, the text is inserted correctly and the cursor position is still at the right place but the UITextView scrolls to the bottom. When I then add another piece of text at the top it scrolls up to the "correct" position. This pattern then repeats for every entered piece of text at a line other than the last, making the UITextView scroll up and down for every button pressed.
I also tried calling UITextView scrollRangeToVisible: passing the selectedRange property as argument after setting the new text. That didn't work either.
I finally tried setting selectedRange after a 0.5 s delay after I set the text. Then it works as it should, but only after the UITextView has first been scrolled down to the bottom for 0.5 s. This seems to indicate that the setText method of UITextView is asynchronous in some way, and completes after I have already set selectedRange or called scrollRangeToVisible, and readjusts the UITextView to what it believes is the desired.
Can anyone tell me what is going on, and how I can get around the problem.
Thanks!
The auto scroll behavior of UITextFields can be annoying and difficult to harness at times.
Do you need the user to manually edit the text? If not, use a multiline UILabel.
If yes, also use a multiline UILabel and exchange it on the fly against a UITextView once the user taps. Change it back on didEndEditing. This techniques has worked well for me in table views.
I solved the problem!
When starting in the maze of creating a custom input view, I began implementing UITextInput and I found that the UITextInput protocol declares many interesting methods. And what is awesome is that UITextView implements that protocol. So even though it's not in the immediate UITextView API reference, you can call all UITextInput methods on your UITextView. For instance insertText: (from UIKeyInput protocol) and replaceRange:withText:. They made it much more flexible to programmatically work with a UITextView. Hope this can help someone else too!

add button in textview -xcode

How can I add a button in textview? for example..
textView.text=#"text here\n\n text also here\n\n text here aswell";
How can I add a button after each "\n\n" or along the text?
You can create a object of UIButton and add it as subview to yout textview.
You need to preset the frame of the button So the text must be statis and you must know the position of the button in advance.
so your \n\n creates a paragraphs
You can do it without static text just split your text in separate textviews by \n\n, add them to your scrollview. You have to measure your text paragraphs height to set the right frame for textviews and leave gaps for buttons. I would rather use tableview so you dont have to worry about that. Add buttons in between, it is doable.
you may reconsider adding buttons along the text this way (you can but it is really convoluted way of doing things), use webview for that as already stated here by others

Resources