Is there any way to tell if UILabel has its text set using label.attributedText
or label.text
property?
The problem is when you set attributedText
, text
is also updated and vice versa, so it is not possible to check these properties for nil.
Is there any way to tell if UILabel has its text set using label.attributedText
or label.text
property?
The problem is when you set attributedText
, text
is also updated and vice versa, so it is not possible to check these properties for nil.
This is what I use. If range length equals the unattributed text length then the text only has a single attribute and is therefore unattributed.
NSRange range;
[label.attributedText attributesAtIndex:0 effectiveRange:&range];
BOOL isAttributed = label.text.length==range.length;
BOOL isAttributed = label.text.length!=range.length
. –
Crenelate attributedText.string
length is 0
(At least when I ported it to swift). I will post an updated answer with my implementation below. –
Stoplight Inspired by @lukas-o I have written an extension on UILabel
that determines if it contains an attributedText
or not. In fact if the NSAttributedString
does not contain any attributes, this computed property will evaluate it to not be attributed.
extension UILabel {
var isAttributed: Bool {
guard let attributedText = attributedText else { return false }
let range = NSMakeRange(0, attributedText.length)
var allAttributes = [Dictionary<String, Any>]()
attributedText.enumerateAttributes(in: range, options: []) { attributes, _, _ in
allAttributes.append(attributes)
}
return allAttributes.count > 1
}
}
> 1
instead of > 0
(or just use return !allAttributes.isEmpty
)? You as a reader can test isEmpty
, sorry for the confusion –
Raynold From the apple docs:
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 other style-related properties so that they reflect the style information starting at location 0 in the attributed string.
You are right, it's not possible to find that out checking one or the other for nil. One way you could know that the text is attributed would be to use something like:
NSMutableArray *strAttrs = [NSMutableArray new];
NSMutableArray *strRanges = [NSMutableArray new];
[label.attributedText enumerateAttributesInRange:NSMakeRange(0, label.attributedText.length) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
[strAttrs addObject:attrs];
[strRanges addObject:[NSValue valueWithRange:(range)]];
}];
This way you could get see whether more than one attribute is there. You could also compare the attributes whether they match your standard attributes and assume that the text property has been set only in this case.
This is what I use. If range length equals the unattributed text length then the text only has a single attribute and is therefore unattributed.
NSRange range;
[label.attributedText attributesAtIndex:0 effectiveRange:&range];
BOOL isAttributed = label.text.length==range.length;
BOOL isAttributed = label.text.length!=range.length
. –
Crenelate attributedText.string
length is 0
(At least when I ported it to swift). I will post an updated answer with my implementation below. –
Stoplight Here is the implementation I came up with, with some slightly altered logic. It is a Swift port of @Vallette 's accepted answer, with additional guard statements.
The function will only return true
if the attributedText
is not nil, not empty, and has at least one attribute that does not apply across the entire range of the text:
extension UILabel {
var isPartiallyAttributed: Bool {
guard let attributedText = attributedText else {
return false
}
guard !attributedText.string.isEmpty else {
return false
}
var range = NSRange()
attributedText.attributes(at: 0, effectiveRange: &range)
return attributedText.string.count != range.length
}
}
The better way would be to check if Range
length of attributes are the same as length of the string. If it's the same you can assume this is non-attributed label.
However, i don't know 100%
reliable way to check for attributed text if NSAttributes
are applied to the whole UILabel
text.
private extension UILabel {
var hasAttributedText: Bool {
guard let attributedText = attributedText,
attributedText.string.isEmpty == false else { return false }
var range = NSRange(location: 0, length: attributedText.length)
_ = attributedText.attributes(at: 0,
effectiveRange: &range)
return range.length != attributedText.length
}
}
© 2022 - 2024 — McMap. All rights reserved.