How to change character background opacity? - swift

I am using Swift 5.
My first test was to change the background of my label and use the opacity. It is ok, but now I would like to try to change the character's background opacity only and not the full background label.
For this, I have no idea where to start.
Any hints?
Thanks

you can try this, change AlphaComponent value according to you preference:
let text = "your label text"
let attributedString = NSMutableAttributedString(string: text)
attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red.withAlphaComponent(0.5), range: NSRange(location: 0, length: attributedString.length))
label.attributedText = attributedString

You can use
sender.alpha = 0.5

Related

NSTextAttachment image in attributed text with foreground colour

When I add an image attachment to an UITextView with a foreground colour set, the image is blanked out with the set colour:
let attrString = NSMutableAttributedString(string: rawText, attributes: [.font: UIFont.systemFont(ofSize: 17), .foregroundColor: UIColor.black])
let attachment = NSTextAttachment(image: image)
let imgStr = NSMutableAttributedString(attachment: attachment)
attrString.append(imgStr)
textview.attributedText = attrString
When I removed .foregroundColor: UIColor.black, the image is displayed correctly, but I need to be able to set the attributed text colour.
I tried to explicitly remove the .foregroundColor attribute after adding the image attachment with no luck. I also tried to remove the .foregroundColor attribute from most of the text and it still wouldn't work, only removing the attribute from the entire string works:
attrString.removeAttribute(.foregroundColor, range: NSRange(location: attrString.length-1, length: 1)) // does not work
// -------
attrString.removeAttribute(.foregroundColor, range: NSRange(location: 1, length: attrString.length-1)) // does not work
// -------
attrString.removeAttribute(.foregroundColor, range: NSRange(location: 0, length: attrString.length)) // works but no text colour
This is developed on Xcode 11.0, iOS 13. Is this a UITextView/iOS bug or an expected behaviour (which, I don't think is likely)? How do I display the image correctly with the text colour set?
It looks like there is a bug with the NSTextAttachment(image:) constructor (on iOS 13, at the time of this answer), the following image attachment construction works correctly:
let attachment = NSTextAttachment()
attachment.image = image

Attributed string cutting and displaying single word into two lines on UILabel

I'm creating attributed text using following attributes,
func attributedString(font: UIFont, contentColor: UIColor, alignment: NSTextAlignment) -> NSAttributedString {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 0.6
paragraphStyle.lineHeightMultiple = 0.8
paragraphStyle.alignment = alignment
paragraphStyle.lineBreakMode = .byWordWrapping
let lineSpacingAttribute: [NSAttributedStringKey: Any] = [NSAttributedStringKey.paragraphStyle: paragraphStyle, NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: contentColor]
let attributedString = NSAttributedString(string: self, attributes: lineSpacingAttribute)
return attributedString
}
I'm displaying this text on UILabel inside a custom tableViewCell. But, it is cutting a single word into two (cutting last letter of a word and displaying it on next line). I've set the numberOfLines to zero, and preferredMaxLayoutWidth for label. And I'm using a custom font.
This problem is happening on small screens only, iPhone SE and iPhone 5S simulators. But, on other simulators it is displaying correctly. Could you please help me to figure out what is wrong in this?
Thanks!
From Apple doc:
var preferredMaxLayoutWidth: CGFloat
This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text flows to one or more new lines, increasing the height of the label.
Depending on your text you can use the adjustsFontSizeToFitWidth property with the minimumScaleFactor property

WKInterfaceLabel Attributed String Fails on Width

I am using an attributed string to strikethrough text in a WKInterfaceLabel. This works up until the point where the text is longer than the width of the watch and therefore you see ... Actually the same thing happens on iOS; however, you can clip content which resolves the issue. On the watch, clipping is not available.
How can I strikethrough the visible text when the overall width is beyond the screen's bounds? Below is the code:
let attributedString = NSMutableAttributedString(string: self.fileTextArray[i])
attributedString.addAttribute(NSStrikethroughStyleAttributeName, value: NSNumber(value: NSUnderlineStyle.styleThick.rawValue), range: NSMakeRange(0, attributedString.length))
attributedString.addAttribute(NSStrikethroughColorAttributeName, value: UIColor.red, range: NSMakeRange(0, attributedString.length))
row.translatedTextLabel.setAttributedText(attributedString)
This appears to be a bug but one with a workaround. The fix is to use the following line of code:
attributedString.addAttribute(NSBaselineOffsetAttributeName, value: 0, range: NSMakeRange(0, attributedString.length))
This solves it in both Watch OS as well as iOS.
Additional detail here: iOS 10.3: NSStrikethroughStyleAttributeName is not rendered if applied to a sub range of NSMutableAttributedString

Multi-line UILabel not resizing text when using attributedText

I am trying to make a very custom UILabel. When viewDidAppear is called, the UILabel's attributedText property is set. This UILabel needs to be 2 lines. I have minimumFontSize set to 7 and numberOfLines set to 2 in storyboard.
Here is my code:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 8.0
paragraphStyle.alignment = NSTextAlignment.Right
let name = idea?.valueForKey("name") as! String
let text = "You submitted your name " + name
let attrString = NSMutableAttributedString(string: text)
attrString.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(12.00), range: NSMakeRange(0,attrString.length))
attrString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attrString.length))
attrString.addAttribute(NSForegroundColorAttributeName, value: UIColor(r: 84, g: 105, b: 121, a: 1.0), range: NSMakeRange(0, 3))
attrString.addAttribute(NSForegroundColorAttributeName, value: UIColor(r: 84, g: 105, b: 121, a: 1.0), range: NSMakeRange(attrString.length - name.characters.count, name.characters.count))
submittedComment.attributedText = attrString
ISSUE: The newly set text for the UILabel is not resized to fit within the UILabel.
Am I missing something? It seems like every new major iOS update changes the way this occurs. Thanks!
Solved:
There were two main errors I found:
It seems that setting the lineSpacing on an NSMutableAttributedString will hide some of the text. From what I've tested, it doesn't seem like the autoresizing feature of UILabel considers this when resizing.
My UILabel had a set width and height. The issue here was setting the height, which wasn't necessary in my case. Once I removed it, my attributedText was no longer hidden.
hope this helps!
Sometimes it's enough to just layout the view again to consider the lineSpacing. For example in my case I had to do the following:
let cell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.descriptionCell, for: indexPath)!
cell.label.text = "Long text with multiple line breaks."
+ " In the nib the attributedText style including the paragaphStyle is configured"
+ " so just set the text here"
cell.layoutIfNeeded()
return cell

Underline text in a UITextView

How can I underline text in a UITextView. I understand that I would need to create a subclass of UITextView, but what would go under drawRect:?
Thanks.
Try to use NSAttributedString as follows and set in UITextView. This works for iOS6.
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:#"Some String"];
[attString addAttribute:(NSString*)kCTUnderlineStyleAttributeName
value:[NSNumber numberWithInt:kCTUnderlineStyleSingle]
range:(NSRange){0,[attString length]}];
For more info on NSAttributedString check this How do you use NSAttributedString?
For eg:-
textView.attributedText = attString;
From apple documentation on UITextView,
In iOS 6 and later, this class supports multiple text styles through
use of the attributedText property. (Styled text is not supported in
earlier versions of iOS.) Setting a value for this property causes the
text view to use the style information provided in the attributed
string. You can still use the font, textColor, and textAlignment
properties to set style attributes, but those properties apply to all
of the text in the text view.
attributedText:
The styled text displayed by the text view.
#property(nonatomic,copy) NSAttributedString *attributedText
Discussion: This property is nil by default. Assigning a new value to this property also replaces the value of the text property with the same string data, albeit without any formatting information. In addition, assigning a new a value updates the values in the font, textColor, and textAlignment properties so that they reflect the style information starting at location 0 in the attributed string.
If you want to avoid having to include CoreText, you can utilize an attributed string with this attribute:
#{NSUnderlineStyleAttributeName: #(NSUnderlineStyleSingle)}
If this is static text, you can underline it in Interface Builder. Make sure to make the text 'Attributed' first by selecting 'Attributed' in the drop down menu:
textViewMessage.linkTextAttributes = #{NSForegroundColorAttributeName: [UIColor blueColor], NSUnderlineStyleAttributeName: [NSNumber numberWithInt:NSUnderlineStyleSingle]};
If you want to format your text (with underlined words, links, colored words...) I suggest you to use FTCoreText
-(IBAction)underline:(id)sender
{
NSDictionary *underlineAttribute = #{NSUnderlineStyleAttributeName: #(NSUnderlineStyleSingle)};
texts.attributedText = [[NSAttributedString alloc] initWithString:texts.text
attributes:underlineAttribute];
}
You can't use "kCTUnderlineStyleAttributeName" or "kCTUnderlineStyleSingle"
Now you must do it like this:
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:#"Text"];
[attString addAttribute:NSUnderlineStyleAttributeName
value:#(NSUnderlineStyleSingle)
range:(NSRange){0,[attString length]}];
If you are using iOS 6 then you can use the attributedText attribute of UITextView. Apply underline formatting to the text. You can also set the typingAttributes property to ensure the text that the user types has a specific set of formatting if you wish.
I recommend you to use CoreText. A Basic tutorial is here on raywenderlich.
I recommend you to use MFUnderlinedTextView, it will be helpful.
This is how I did it using Swift 5:
let attributedString = NSMutableAttributedString(string: myTextView.text ?? "")
myTextView.linkTextAttributes = [NSAttributedString.Key(rawValue: NSAttributedString.Key.underlineStyle.rawValue): NSUnderlineStyle.single.rawValue] as [NSAttributedString.Key: Any]?
myTextView.attributedText = attributedString
Swift 5.
As my UITextView if for inserting text, I created an extension function as bellow.
extension UITextView {
func underlined() {
let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = UIColor.lightGray.cgColor
border.frame = CGRect(x: 0, y: self.frame.size.height - 5, width: self.frame.size.width, height: 1)
border.borderWidth = width
self.layer.addSublayer(border)
self.layer.masksToBounds = true
let style = NSMutableParagraphStyle()
style.lineSpacing = 15
let attributes = [NSAttributedString.Key.paragraphStyle : style, NSAttributedString.Key.foregroundColor : UIColor.darkGray, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 13)]
self.attributedText = NSAttributedString(string: self.text, attributes: attributes)
}
}
The border is drawling the line and the style is adding the spacing between the lines.
Usage in your UIView custom layout:
override func layoutSubviews() {
super.layoutSubviews()
self.dateAndTimeInput.underlined()
}
Image with the result
let someString = NSMutableAttributedString(string: "Your String", attributes: [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 20), NSAttributedString.Key.underlineStyle : NSUnderlineStyle.single.rawValue])
someStringTextView.attributedText = titleAT
U can just give your string a bunch of attributes like bold, underlined etc.
To underline a text, you have to go where you can select copy, cut , delete options there are now more options like B/I/U( bold, italic, underline). Choose this option and this is it. And to unable it, choose underline option again.