Replace UITextView selected text with NSAttributedString - ios

I'm trying to replace some text that was selected inside a UITextView with some NSAttributedString but only the following method is available:
textView.replace(UITextRange, withText: String)
As you can see, replacing text only accepts a String and I cannot find way to replace it with an NSAttributedString.
One thing I could do is to store the whole UITextView attributedText and then perform the desired changes on a NSMutableAttributedString and then I can replace the UITextView.attributedText to be the one of the NSMutableAttributedString, but this comes with some issues for me.
If the text is already long with some NSStorage and NSAttachments this will be way more expensive.
Is there any workaround?

Because you can't intermix String and NSAttributedString, there's unfortunately no workaround that will let both co-exist in a text field.
But you should be able to use replaceCharacters(in:with:):
existingAttributedString.replaceCharacters(in: range, with: replacementAttributedString)

Related

Apply font for certain string

I have a "$" symbol in my app. And I want this char to apply a custom font in every string that contains this symbol. I know that font is related to UILabel but can I relate it to string? Is it possible to make it once and automate it?
The short answer is No. There is no way to automate that.
Essentially what you would have to do is set the attributedText property of the UILabel with an NSAttributedString that applied the correct style settings to symbol when it was found.
So you might create a function that takes a string and creates an NSAttributed string for it with your desired font settings wherever the symbol is found. Then you could add a method to UILabel to accept a string, pass it through your function, and set the attributedText of the label
But it's going to take some work on your part.

Detect link attribute and callout as link for NSAttributedString in iOS

I have a link within an attributed string that is being then set for a textview. For Accessibility purpose, I want that link to be called out as a link trait, is it currently possible for an attributed string to call out different traits within the string? If not what could be an ideal solution to do that then?
You can look for all the "style runs" of attributes within the text view's attributed text by calling attributes(at:longestEffectiveRange:in:) repeatedly until you come to the style run you want. Thus you can locate the link and obtain its value.

get the attributed string from uitextview

I need to get the attributed string from UITextView. For example if user has formatted the text to bold or italic i need to save in variable or display in label as it is. Please guide me how to do this.
Thanks in advance!
I'm not sure what you're asking here, but UITextView has an attributedText property, so you can just get this by doing:
yourTextView.attributedText
Remember that an attributed string doesn't have only one attribute for the whole string (like an NSString), but depending on the index, it can have different attributes (so the first word can be in bold, and the second one can be italic).
To retrieve an attribute on a given index you can use the following property:
attributedString.attribute("your attribute", atIndex: yourIndex, effectiveRange: yourRange)
You can see more ways of accessing the attributes here.
You could do so:
UITextView *txtView;
UILabel *label;
self.label.attributedText = self.txtView.attributedText;

How to fix UILabel padding issue?

I have a UILabel and whenever I set its outlet the padding I created in Storyboards for it under attributed text disappears like it was never there. The text the stays stuck on the left side. How can I fix this issue?
#IBOutlet weak var mycoollabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
mycoollabel.text = "Wow"
}
Note: OP clarified in a comment that they are setting their padding using attributed text in Interface Builder.
The problem here is a confusion between text and attributed text, or, because these are code, it's text and attributedText.
On iOS, lots of things have a text property, and it's just a simple string of text that gets displayed somewhere without any sort of formatting. Usually the formatting is attached to the object that is showing the text, e.g. a label has a text colour and alignment properties that make its text look however you want.
On iOS, most (all?) of those things also have an attributedText property, which is a very different beast. Attributed text contains a string but also specific formatting instructions required to display that string – text attributes, hence the name.
So, OP is creating an attributed text configuration in their storyboard, then, in code, modifying the text property. This will overwrite their formatted string with a plain string, losing its layout configuration.
If you're looking to create an attributed string with a first line indent, you should try this:
let ps = NSMutableParagraphStyle();
ps.firstLineHeadIndent = 50
let attrs = [NSParagraphStyleAttributeName: ps]
let attributedString = NSAttributedString(string: "Hello, world!", attributes: attrs)
label.attributedText = attributedString
Note that there are a few different options available to you here, so you might need to find the right type of indent for your precise needs. If you right-click on NSMutableParagraphStyle and choose Jump To Definition you'll see all the options.
That's because a UILabel can have either plain text or attributed text. You set attributed text in the storyboard, and add some formatting (padding, etc.). Then, in code, you override that text (and all its formatting) with plain text.
If you want to keep the formatting, you need to set the label's attributedText property. And add all the necessary formatting to the NSAttributedString object you create for that.

What happens if I set both UILabel.text and UILabel.attributedText?

I have an attributed string which I am making out of HTML using DTCoreText, and I want to set it as the value of my UILabel. However, I want to check at a later point if the value of the string has changed, in comparison to the UILabel. Is it possible to set both the UILabel's text and attributedText properties? Will the attributedText simply overshadow the text property, so the text property can be kept as an internal value?
According to the documentation, assigning to text replaces attributedText with the same contents (albeit as an unstyled attributed string), and assigning to attributedText replaces text with the same contents (without any formatting information).
If you want to attach arbitrary information to an obj-c object, you should use associated objects.

Resources