获取NSAttributedString属性的方法

在封装一个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 是否停止遍历

下面我讲讲方法是如何遍历的。
如图:
带属性的alertView

如果在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!!第一次写博客,技术也有限,写不好的地方希望大神们见谅,如果有好的建议,或者更好的方案希望各位大神指点指点。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值