最近接到一个需求,文本长度为2-3个文字,两个文字长度的文本要求中间存在空距,左右顶边,且整体文本长度与三个文字的文本长度保持一致。效果如下:
最简单的实现是让UI把文字做成图片直接使用。第二种则是文本内加空格:1
[NSString stringWithFormat:@"爱 好:"];
但是这种方法的问题在于由于文字font的存在,有时候,添加空格后文本的长度无法与三个文字的文本长度一致。这时候我们还可以选择第三种方案,保持文字长度一致,再遮盖部分文字,保留显示文字:1
2
3
4
5
6居住地:____ 职一业:____
爱一好:____ 电一话:____
职一业: -> 职 业:
爱一好: -> 爱 好:
电一话: -> 电 话:
具体实现上,我们通过NSAttributedString
的分类方法实现。将原有字符转换为属性字符,并设置文字属性、遮盖范围及遮盖部分的文字属性:1
2
3
4
5
6
7
8
9
10
11
12
13
14+ (NSAttributedString *)attributedStringWithString:(NSString *)string attributes:(NSDictionary<NSString *, id> *)attrs maskRange:(NSRange)maskRange maskAttributes:(NSDictionary<NSString *, id> *)maskAttrs
{
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:attrs];
if (NSEqualRanges(maskRange, NSRangeZero)) return attributedString;
NSRange stringRange = NSMakeRangeFromString(string);
if (NSRangeInRange(maskRange, stringRange))
{
[attributedString addAttributes:maskAttrs range:maskRange];
}
return attributedString;
}
在这里,我们先将文字整体转换为指定属性的文字。之后获取文字范围,当遮盖范围在文字范围内则实现遮盖文字效果。获取文字范围和判断遮盖范围是否在文字范围内,我们可以通过在NSValue
的分类方法内添加内联函数方法的形式实现:
获取字符串的range:1
2
3
4NS_INLINE NSRange NSMakeRangeFromString(NSString *string)
{
return NSMakeRange(0, string.length);
}
判断range1是否包含于range2内:1
2
3
4NS_INLINE BOOL NSRangeInRange(NSRange range1, NSRange range2)
{
return (NSLocationInRange(range1.location, range2) && range1.length <= (range2.length - range1.location)) ? YES : NO;
}
同时,我们也可以提供一个便利方法处理此类需求,将原有字符转换为属性字符,并设置文字颜色、文字格式及遮盖范围,遮盖效果默认为透明颜色:1
2
3
4+ (NSAttributedString *)attributedStringWithString:(NSString *)string textColor:(UIColor *)color font:(UIFont *)font maskRange:(NSRange)maskRange
{
return [NSAttributedString attributedStringWithString:string attributes:@{NSFontAttributeName:font, NSForegroundColorAttributeName:color} maskRange:maskRange maskAttributes:@{NSForegroundColorAttributeName:[UIColor clearColor]}];
}
为方便代码管理,在具体调用界面,我们可以参考UITableView
与NSIndexPath(UITableView)
, 根据界面需求,为调用界面添加专用的NSAttributeString
分类方法:1
2
3
4
5
6
7
8@implementation NSAttributedString (AdjustTestTitle)
+ (NSAttributedString *)attributedTitleWithString:(NSString *)string maskRange:(NSRange)maskRange
{
return [NSAttributedString attributedStringWithString:string textColor:[UIColor blackColor] font:[UIFont fontWithName:@"Arial" size:19.f] maskRange:maskRange];
}
@end
最后,在需要调用的位置调用即可:1
self.leftTitleLabel.attributedText = [NSAttributedString attributedTitleWithString:@“职一业:" maskRange:NSMakeRange(1, 1)];
附,示例代码:https://github.com/ColinHwang/iOS-TextMasked
参考资料:
[1]Apple Inc.NSAttributedString Classs Reference[EB/OL].https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/index.html ,2016-6-23.