在封装一个alertView的时候,需要设置颜色和行距,字距,所有要用到富文本,在封装alertView的时候,留下一个开放的接口
/**
* 带有属性的内容
*/
@property (nonatomic,copy)NSAttributedString *attributeMassage;
设置内容alertView的attributeMassage会自动计算高度和尺寸,所有会用到以下方法
- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSDictionary<NSString *, id> *attrs, NSRange range, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateAttribute:(NSString *)attrName inRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(id _Nullable value, NSRange range, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
-
typedef NS_OPTIONS(NSUInteger, NSAttributedStringEnumerationOptions) {
NSAttributedStringEnumerationReverse = (1UL << 1),
NSAttributedStringEnumerationLongestEffectiveRangeNotRequired = (1UL << 20)
};
两个方法都是遍历NSAttributedString带有的属性,一个是不指定属性名称,一个指定属性名称;
enumerationRange:遍历的范围
opts:遍历方式 NSAttributedStringEnumerationReverse反向遍历;NSAttributedStringEnumerationLongestEffectiveRangeNotRequired正向遍历;
block:attrs属性在这个字典里;range带属性的范围;stop 是否停止遍历
下面我讲讲方法是如何遍历的。
如图:
如果在block中打印对应的string。
[attributeMassage enumerateAttributesInRange:NSMakeRange(0, attributeMassage.length) options:1 usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
NSLog(@"%@",[attributeMassage attributedSubstringFromRange:range]);
}];
那么打印结果就是:
1、“ 进入公积金查验后,请选择您缴纳”;
2、“公积金所在地”
3、“,填写公积金账号和密码;公积金账号是您”
4、“公积金卡”
5、“的账号号码;如您忘记密码请登录您缴纳地的”
6、“公积金官网”
7、“找回/重置密码。”
如果 options为NSAttributedStringEnumerationReverse;
那么打印结果就是从“找回/重置密码。”开始打印;
结论:方法会根据不同属性遍历,每次发现一个文字与上个文字的属于不一致就会执行block。
自动计算高度方法:
//影响高度计算的几个属性:一个是字体大小、一个行距、一个字距;
- (void)setAttributeMassage:(NSAttributedString *)attributeMassage{
_attributeMassage = attributeMassage;
NSString *str = attributeMassage.string;
__block NSMutableDictionary<NSString *,id> * _Nonnull attrsDict;
__block UIFont *font;
[attributeMassage enumerateAttributesInRange:NSMakeRange(0, attributeMassage.length) options:1 usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
//只要有属性字典就停止遍历。因为我的需求字体大小都一样,颜色上变化而已,颜色不影响高度计算
if (attrs) {
*stop = YES;
}
attrsDict = [NSMutableDictionary dictionaryWithDictionary:attrs];
font = [attrs valueForKey:NSFontAttributeName];
}];
//这里要获取 attributeMassage 是否设置了字体大小的属性,如果没设置的话要获取UILable的字体大小,不然计算可能会有误差;
if (!font) {
[attrsDict setObject:messageLab.font forKey:NSFontAttributeName];
}
//拿到属性后再计算高度
CGFloat height = [str boundingRectWithSize:CGSizeMake(messageLab.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDict context:nil].size.height;
messageLab.height = height;
messageLab.attributedText = attributeMassage;
}
是不是soeasy!!第一次写博客,技术也有限,写不好的地方希望大神们见谅,如果有好的建议,或者更好的方案希望各位大神指点指点。