Have background color wrap UILabel [duplicate] - ios

This question already has answers here:
How to highlight only text in UILabel - IOS
(4 answers)
Closed 5 years ago.
I am trying to display the following
But when setting the text background color it extends the entire background and fills much than I would like as I am just trying to apply a "highlight" text feature. Any ideas would be greatly appreciated

You can do it as - first iterates line in your text and then apply background color with lines. Here i used Multi-line String Literals.
By using NSBackgroundColorAttributeName apply color to lines.
#IBOutlet weak var myLabel: UILabel!
myLabel.text = """
GET
MORE LIVES
"""
myLabel.numberOfLines = 0
let attributeString = NSMutableAttributedString(string: myLabel.text!)
let labelText = myLabel.text!
var lines: [String] = []
labelText.enumerateLines { line, _ in
lines.append(line)
}
print(lines)//lines in your text
var startIndex = 0
for value in lines {
//Apply background color to lines
attributeString.addAttribute(NSBackgroundColorAttributeName, value: UIColor.red, range: NSRange(location: startIndex, length: value.characters.count))
startIndex = startIndex + value.characters.count + 1
//startIndex will locate new line's first index
}
//Assign attributedText to your label
myLabel.attributedText = attributeString

We cannot wrap the colour of a view in iOS, The possibilities are
Keeping duplicate UILabels as Nathan said.
Designing a canvas and and assign it to "UIImageView".
I think last possibility is the better way to implement
You can also view my GitHub repository regarding this query.

Related

Swift how to add background color just around text in a label?

How do you add a background color around each variable inside the interests variable? Just around text not the spaces.
var interests = "\(int01) \(int02) \(int03) \(int04) \(int05) \(int06)"
I want it to look like this:
You can use a regex to find anything but white spaces, use a while loop to find its occurrences in a string and use those ranges to change the background color of an attributed string:
Swift 4
let mutable = NSMutableAttributedString(string: interests)
var startIndex = interests.startIndex
while let range = interests.range(of: "\\S+", options: .regularExpression, range: startIndex..<interests.endIndex) {
mutable.addAttribute(.backgroundColor, value: UIColor.cyan, range: NSRange(range, in: interests))
startIndex = range.upperBound
}
label.attributedText = mutable
Note: If you would like to add space around your text you can change your regex to " \\S+ " and don't forget to add spaces at the begin and at the end of your original interests string.
let attributedString = NSMutableAttributedString(string: interests)
attributedString.addAttribute(NSBackgroundColorAttributeName, value: yourColor, range: NSMakeRange(startOfWord, lengthOfWord))
What you can do is use a UICollectionView with cells that have labels that span the entire cell. Each cell then corresponds to individual words. That way you can set either the label or the cell background color to whatever you want.
For ease of implementation, I would turn your interests variable into an array of strings. That way you can easily count the number of cells you need and give each cell the right string.

Read/see More at the end of the label

I am trying to create a read more button at the end of my label. I want it to display 3 lines by default. I am coding in swift not objective c. Only when the user clicks the read more part of the label, should the label expand. It should look and work exactly like it does on instagram except on Instagram, it is in a tableview cell. My label and read more button will be in a scrollview. I have managed to get the expanding and contracting part working by adjusting the number of lines property of the label.
if descriptionLabel.numberOfLines == 0{
descriptionLabel.numberOfLines = 3
}else {
descriptionLabel.numberOfLines = 0
}
descriptionLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
I am having problems with putting a "...more" at the end of the label and cutting the text off at the right place. I have looked at other people's responses to similar questions but nothing seems to work properly.
I can put a button over the last line of text so making the see more part of the label clickable also isn't the problem. The problem I am having is truncating the text at the right place and placing the see more text at the right place so that it displays.
I also want the read more button to only appear when it is necessary. I don't want to it appear when there are only 1-3 lines of text. This is also something I am having issues with.
I can't use this https://github.com/apploft/ExpandableLabel because it does not support scrollviews just tableviews.
the swift solution here didn't work: Add "...Read More" to the end of UILabel. It crashed the app.
Finally, the read more button should be in line with the last line of text and at the end of it. It would be an added benefit it this worked in a tableview cell as well!
I found ReadMoreTextView in Github, which is based on UITextView. The key method in this library is the following:
private func characterIndexBeforeTrim(range rangeThatFits: NSRange) -> Int {
if let text = attributedReadMoreText {
let readMoreBoundingRect = attributedReadMoreText(text: text, boundingRectThatFits: textContainer.size)
let lastCharacterRect = layoutManager.boundingRectForCharacterRange(range: NSMakeRange(NSMaxRange(rangeThatFits)-1, 1), inTextContainer: textContainer)
var point = lastCharacterRect.origin
point.x = textContainer.size.width - ceil(readMoreBoundingRect.size.width)
let glyphIndex = layoutManager.glyphIndex(for: point, in: textContainer, fractionOfDistanceThroughGlyph: nil)
let characterIndex = layoutManager.characterIndexForGlyph(at: glyphIndex)
return characterIndex - 1
} else {
return NSMaxRange(rangeThatFits) - readMoreText!.length
}
}
To display text like "xxxx...Read More", the library
Get how many characters could be display in the UITextView: Use NSLayoutManager.characterRange(forGlyphRange:, actualGlyphRange:)
Get the position of the last visible character and the width of "...Read More": Use NSLayoutManager.boundingRect(forGlyphRange glyphRange: NSRange, in container: NSTextContainer)
Get the character index before trimming: Use NSLayoutManager.characterIndexForGlyph(at glyphIndex: Int)
Replace text which should be trimmed with "...Read More": UITextStorage.replaceCharacters(in range: NSRange, with attrString: NSAttributedString)
Please check :
func addSeeMore(str: String, maxLength: Int) -> NSAttributedString {
var attributedString = NSAttributedString()
let index: String.Index = str.characters.index(str.startIndex, offsetBy: maxLength)
let editedText = String(str.prefix(upTo: index)) + "... See More"
attributedString = NSAttributedString(string: editedText)
return attributedString
}
You can use like :
let str = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
descriptionLabel.attributedText = addSeeMore(str: str, maxLength: 20)
// Output : Lorem Ipsum is simpl... See More

iOS - image attachment for the text view changes attributes

I've a UITextView described as follows with the given attributes:
lazy var inputTextView: UITextView = {
let tv = UITextView()
tv.backgroundColor = .white
tv.textContainerInset = UIEdgeInsetsMake(12, 12, 12, 12) // Posicionamento do texto
let spacing = NSMutableParagraphStyle()
spacing.lineSpacing = 4
let attr = [NSParagraphStyleAttributeName : spacing, NSFontAttributeName: UIFont.systemFont(ofSize: 16), NSForegroundColorAttributeName: UIColor.blue]
tv.typingAttributes = attr
return tv
}()
Everything works as expected until I attach an image to the UITextView.
The image gets inserted in the desired position but after its inserted it overrides my textView attributes.
The text becomes small and in a different color than the attributes I've implemented in its declaration.
I'm attaching the image as follows:
let att = NSTextAttachment()
att.image = image
let attrString = NSAttributedString(attachment: att)
self.inputTextView.textStorage.insert(attrString, at: self.currentCursorLocation)
What's causing this issue?
I've even tried to reenforce its attributes whenever I insert an UIImage to its content.
I've tried the following when adding the image:
let att = NSTextAttachment()
att.image = image
let attrString = NSAttributedString(attachment: att)
self.inputTextView.textStorage.insert(attrString, at: self.currentCursorLocation)
let spacing = NSMutableParagraphStyle()
spacing.lineSpacing = 4
let attr = [NSParagraphStyleAttributeName : spacing, NSFontAttributeName: UIFont.systemFont(ofSize: 16), NSForegroundColorAttributeName: UIColor.blue]
self.inputTextView.typingAttributes = attr
And it still doesn't change its attributes.
Whats causing this issue? Any tip?
Thanks
Edit
As suggested here's how I'm setting the cursor position
func textViewDidChange(_ textView: UITextView) {
currentCursorLocation = textView.selectedRange.location
}
I do this to insert the image at the current location of the text blinking cursor
[Edit: Unfortunately this does not solve Ivan's problem - I leave the answer because it is interesting detail for those who do not understand Unicode character encoding].
String range specification is non-intuitive due to the subtleties of Unicode. I expect your issue is that the cursor position at which you are inserting your image is not where you think it is relative to the text and you are inserting the image at a Unicode scalar position that is not between Unicode code points, such that you are corrupting a unicode code. To understand why this can happen, see this Apple article.
Strings in Swift 2
I would suggest using the following notation when specifying string ranges (taken from this Stack Overflow answer: NSAttributedString and emojis: issue with positions and lengths).
// Convert to NSRange by computing the integer distances:
let nsRange = NSRange(location: text.utf16.distance(from: text.utf16.startIndex, to: from16),
length: text.utf16.distance(from: from16, to: to16))
However without seeing how you set your cursor position, it is not possible for me to be sure this is the source of your problem. [Update: thanks for updating the question to show the cursor position - we got there in the end but for others, note, after setting the cursor position this way (which would have been fine), he was incrementing it by 1, which meant the issue I have referred to about Unicode scalars versus code points was in fact the issue].

Partially Bold Text in UILabel [duplicate]

This question already has answers here:
How to format certain words of a cell's text label
(3 answers)
Closed 5 years ago.
I have a tableView which has cells populated by two arrays :
var names = ["Marie : ", "Nicolas : " , "Sarah : "]
var colors = ["White" , "Blue" , "Red"]
My cells are populated by my arrays in a single UILabel named "info" :
cell.info.text = names[indexPath.row] + colors[indexPath.row]
Everything works fine, I just don't manage to have my "names" array to appear in bold without touching to the "colors" array.
What would be the best approach to do this ?
Thanks in advance for any help !
If you just want the names to appear in bold, use the UILabel attributedText attribute to set an attributed string instead of a plain text string.
Something like:
let name = names[indexPath.row]
let color = colors[indexPath.row]
let attributedText = NSMutableAttributedString(string: name, attributes:[NSFontAttributeName : UIFont.boldSystemFont(ofSize:15)])
attributedText.append(NSAttributedString(string:color))
cell.info.attributedText = attributedText
Of course, you'd need to set the font in the above for the bold part according to how you have the cell styled.

UILabel text with different font size and color [duplicate]

This question already has answers here:
How do I make an attributed string using Swift?
(31 answers)
Closed 7 years ago.
Howto set different font size and color in a UILabel with Swift?
I need to color the first char of the string with different color and size than the rest of the string.
Suppose you want to have a smaller and gray currency symbol like this:
Just use a NSMutableAttributedString object:
let amountText = NSMutableAttributedString.init(string: "€ 60,00")
// set the custom font and color for the 0,1 range in string
amountText.setAttributes([NSFontAttributeName: UIFont.systemFontOfSize(12),
NSForegroundColorAttributeName: UIColor.grayColor()],
range: NSMakeRange(0, 1))
// if you want, you can add more attributes for different ranges calling .setAttributes many times
// set the attributed string to the UILabel object
myUILabel.attributedText = amountText
Swift 5.3:
let amountText = NSMutableAttributedString.init(string: "€ 60,00")
// set the custom font and color for the 0,1 range in string
amountText.setAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12),
NSAttributedString.Key.foregroundColor: UIColor.gray],
range: NSMakeRange(0, 1))
// if you want, you can add more attributes for different ranges calling .setAttributes many times
// set the attributed string to the UILabel object
// set the attributed string to the UILabel object
myUILabel.attributedText = amountText

Resources