How to reset attributes in NSTextStorage - ios

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.

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

iOS, textView half editable

I need help in string formatting in iOS UITextView. I have a textView, for now it`s editable. Now I want to add a few strings. they should be like header and user must be able to type only under it, and when he press ENTER or DELETE line sting should change their position, so at the end it should look like
Header 1(with color not editable)
/* user can type here
*/
Header 2 (with color not editable)
/* user can type here
*/
I think i need to use delegate and attributed string or something,
but I can`t figure it out. HELP please
The best way to achieve this is to make two labels and two text views on top of a scroll view. like
The heights of two text views can by dynamic depending on the text length. And in this case you can avoid endless IF conditions as you would need to put everything in a single Text view.
The advantage of this approach is the label text format will be very easy to set, you can simply set the attributed string in the storyboard.

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.

Add a Text Link to a TextView

Is it possible to add a text link into a TextView? I want the link to perhaps behave like a button, where I can assign an action to it.
EDIT: When I say assign an action, I mean actually giving it something in the code. I'm wondering if it's possible to dynamically add a "button" into text that I can assign a coded action to.
Live scenario
Think of something like a dictionary app. Maybe the definition of one word uses another word that you might not know the definition of, so being able to click on that word to instantly search it rather than having to type it in would be a nice user friendly feature. It seems rather unlikely, though, I guess.
I would recommend using NIAttributedLabel from Nimbus, an open source iOS library. You can specify text ranges that are links, and you get delegate messages sent when a user taps on it.
Main Nimbus site: http://nimbuskit.info/
NIAttributedLabel docs: http://docs.nimbuskit.info/interface_n_i_attributed_label.html
in the inspector, go to the Text View Attributes tab then make sure "Detect Links" is checked.
Yes you can. Add the URL into the text view, then open up the Attributes Inspector. You will see an option in there to detect links.
I know of a way, but its a LOT of work. First, you have an NSAttributedString that you have the text view display. Second, attribute the range of text you want to be the button. Third, assign a tap gesture recognizer to the text view and in the method called by the recognizer, you'll use core text to determine if the tap happened over the range of text that represents the buttons.
Heres how youll use core text: create a framesetter with the attributed string. Create a frame from the framsetter with the shape of a square that is the frame of the text view, inset by the padding of the text view. The frame will allow you to get the y origins of every line in the text view and and once you know what line the tap happened on, you can use the line to then figure out exactly what character was tapped on that line by giving it an x offset. Once you know character index on the line, you can add it to the beginning of the range of the line and get the index of the character within the whole string. Then you can check if its within the range of the text that is your button. If it is, you can then call a method to simulate a target action type behavior.
Ive explained the process of how to accomplish this and specified what kinds of core text objects youll need, ill let you look up the specific api details:
https://developer.apple.com/library/mac/documentation/Carbon/Reference/CoreText_Framework_Ref/_index.html#//apple_ref/doc/uid/TP40005304
You can also use my objc core text wrapper:
https://github.com/mysterioustrousers/MYSCoreText
What about CoreText? It Can draw many kinds of Text .

UITextView UIResponderStandardEditActions Text Formatting Toggle State

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.

Resources