UITextView UIResponderStandardEditActions Text Formatting Toggle State - ios

How do I determine the current state of the UIResponderStandardEditActions for text formatting? For example, if I do the following:
[textView toggleBoldface:nil];
How do I query the textView to find out if the state of bold is now on or off? This is for just a cursor with no selection (i.e. range length is 0). As such, enumerateAttribute doesn't seem to work.
Thank you.

It appears the typingAttributes property (available in iOS 6) will log the attributes that will be applied to new text typed by the user, even with a selection length of 0. Thus revealing what the state of formatting options such as bold will be.
NSLog(#"textViewFormatting options: %#", [[self noteTextView] typingAttributes]);

I'm not finding anything useful in the docs, but I suppose it would be simple enough to just subclass UITextView, add a property on it like BOOL boldText and then wherever you call [textView toggleBoldFace:nil]; just toggle that property as well. And then when you need to check the state of the textView, just check the boldText property instead.

Related

Array item completion in a UITextView

I'm trying to accomplish an autocomplete of my own for matching array items while typing. So, I already have the logic done for matching what's being typed with what's in the array, but my question is related to displaying the proposed correction in the UITextView like this screenshot
I was trying by splitting the text in the textview and replacing the last word into attributed strings, but that makes the proposed correction part of the actual contents. Any ideas of how this is accomplished in this app?
What you currently do is good , when you set the text of the textView to attributed string make bool flag say it's name is textEdited = true with a string part that the user types say it's name userStr , when textView change method is triggered check that bool and according to it make the search if it's true proceed search with userStr if it's not proceed search with whole textView text , don't forget to make textEdited= false after every zero suggested result
Edit: regarding the cursor put a label under the textfield with the same font as the textView and make it's background darkGray , also make background of the textview transparent and every attributed string assign it to the label so plus part of the label will be shown and cursor will be as it is in the textView

How to reset attributes in NSTextStorage

I am trying to a text parser for iOS. I have some syntax to bold, italic, highlight, etc. I have set it up in a UITextView with an instance of NSTextStorage to monitor the changes and set the correct attributes. If I preload the UITextView with text it works great.
However when I'm typing and let's say I type something like this
==a==
It works great it highlights it yellow and everything is fine. However if I place the cursor right next to the last == and starting typing to create something like this:
==a==hello my name is...
Then the rest of the text also gets highlighted.
I know the regex I use is not the problem because if I pre fill the UITextView with that text it parses it correctly.
Question: So what I need help with is resetting the the current cursor position to no text attributes. I'm not sure how to do that because if it is at the end of the text view I can't go forward because then I get an NSRangeException.
Thanks!
I figured this out, what you have to do is in the delegate for UITextView implement the textViewDidChange: method and set the typingAttributes.
Like this:
- (void)textViewDidChange:(UITextView *)textView {
textview.typingAttributes = #{...};
}
Now every time the text updates it will reset to the default attributes.

UITextInput: selectedTextRange vs. markedTextRange?

Ok, so I know Apple's UITextInput protocol requires the two UITextRange properties selectedTextRange and markedTextRange and the documentation says that selectedTextRange is a subrange of markedTextRange which is an uncomfirmed text range by the user yatta yatta. That still doesn't make some things clear to me regarding how I ought to implement the two text ranges differently. Could someone visually explain to me the difference between selectedTextRange and markedTextRange? I know that when the length of selectedTextRange is 0 it indicates a blinking caret at selectedTextRange's location. But what the heck is "marked text"?? I've only seen the following for text views in iOS:
Which I assume represents the current selectedTextRange. What does markedTextRange look like? Or is it basically the exact same thing? I'm so confused :( Thanks in advance for any help! The documentation has proven itself useless in my understanding of how to implement the UITextInput protocol.
EDIT
Does implementing markedTextRange have anything to do with the fact that some text in a view could be "markable" but "readonly" and selectedTextRange indicates the subrange in the "marked text", markedTextRange, that is readwrite?
From Apple documentation for UITextInput:
Marked text, which is part of multistage text input, represents provisionally
inserted text that the user has yet to confirm. It is styled in a distinctive
way. The range of marked text always contains within it a range of selected
text, which might be a range of characters or the caret.
Hence markedTextRange gets useful with languages that requires multistage input, e.g. Japanese.
In simple words: what user types is yet to be confirmed before it can be added to the value of the text input control is were markedTextRange gets into the game. GIF bellow demonstrates markedTextRange in action:
Notice slight sapphire background behind the unconfirmed hieroglyphs. Once text gets confirmed either by hitting enter/return, selecting option from suggestions or finger tap on text area after the marked text gets added to the input control value and background gets removed.
Notes:
markedTextRange has nothing to do with read-only text
I was not able to achieve multiple symbols selection within markedTextRange

Dynamically change keyboard's return button but preserve type

I have an input field the user needs to fill with an alphanumeric code. The keyboard the user uses to type the code has a dynamic return button that changes to "send" as he writes some text on the field. When the field is empty the return button has the default value.
To dynamically change the return button type I use the following code:
if([textField.text isEqualToString:#""])
{
textField.returnKeyType = UIReturnKeyDefault;
}
else
{
textField.returnKeyType = UIReturnKeySend;
}
[textField reloadInputViews];
However this has the following drawback: since the code is alphanumeric, the user may be typing numbers, and yet the keyboard will always switch back to the letter keyboard, so to type more than one number in a row he will need to be continuously switching to number keyboard.
Is there any way to dynamically change the return key of a keyboard as the user types but to preserve the keyboard state to letters or numbers keyboard?
I think this is not a bug on Apple's side, more a missing implementation of API for the keyboard. With the new iOS8 API you might want to create your own keyboard returning the UIKeyboardType.
For iOS7 I worked around by inspecting the views of the keyboard. Use the US2KeyboardType CocoaPod or the source:
https://github.com/ustwo/US2KeyboardType
As Martin noted above, it's not a bug on Apple's side, but on my side. However I'll be posting the solution I've found since it is the one that solves that particular problem:
Instead of manually changing the return key type when there is text on the text field, Apple provides us with a property called enablesReturnKeyAutomatically that when set to YES it automatically manages the issue, enabling and disabling the return key depending on whether there is text or not in the text field.
Therefore you don't need to modify the returnKeyType property, and thus, no calling to reloadInputViews is required, so the keyboard doesn't change back to its original state.

Code input text field

Is there a native UI control for code input text field, for example like Whatsapp:
No. To achieve this, they're almost certainly tapping into the textField:shouldChangeCharactersInRange:replacementString: method for their UITextField, selectively accepting and formatting user input to match the dash-if-empty approach.
Further, I'm sure they've subclassed the field; per your comments there isn't a blue cursor - which isn't standard for a UITextField.
No there isn't. Use a UITextField, fill it with dashes, keep track of how many characters the user has entered, and replace the dashes accordingly as the user types.
There's a 4-digit code input text field called CodeInputView written in Swift.
In the past I've added a UITextField to the view and set its hidden == true. Then I show/hide the keyboard by calling becomeFirstResponder()/resignFirstResponder() on it. I listen for text did change notifications and update a visible label with the value of the hidden text field.

Resources