(一)前言
有时候项目会遇到,点击一段话中的某一个或者是更多的关键字,需要执行某一个操作;这样用button肯定是行不通的了;TTTAttributedLabel第三方库在很多app应用中都有使用,趁着现在没事,简单的了解一下这个控件。
(二)相关的代码;
(1)写这段段简单的代码的时候也遇到了不少的坑,比如说设置前端的颜色(需要这样写(id)kCTForegroundColorAttributeName),使用NSForegroundColorAttributeName设置是不行的;如果不需要显示下划线的话,在linkAttributes字典中不需要加上下划线的样式(id)kCTUnderlineStyleAttributeName;
TTTAttributedLabel *label = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(50, CGRectGetMaxY(btn.frame)+30, 200, 40)];
label.delegate = self;
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor lightGrayColor];
label.enabledTextCheckingTypes = NSTextCheckingTypePhoneNumber;
label.linkAttributes = @{(id)kCTForegroundColorAttributeName:[UIColor yellowColor]};
[label setText:@"点击 123456 自动拨打电话" afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange boldRange = [[mutableAttributedString string] rangeOfString:@"123456" options:NSCaseInsensitiveSearch];
[mutableAttributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20.0f] range:boldRange];
return mutableAttributedString;
}];
label.activeLinkAttributes = @{(id)kCTForegroundColorAttributeName:[UIColor greenColor]};
label.inactiveLinkAttributes = @{(id)kCTForegroundColorAttributeName:[UIColor blackColor]};
NSRange testRange = [label.text rangeOfString:@"123456"];
//[label addLinkToAddress:@{@"key":@"test"} withRange:testRange];
[label addLinkToPhoneNumber:@"123456" withRange:testRange];
[self.view addSubview:label];
//委托
- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithAddress:(NSDictionary *)addressComponents{
NSLog(@"data -- %@",addressComponents);
}
- (void)attributedLabel:(TTTAttributedLabel *)label didLongPressLinkWithTransitInformation:(NSDictionary *)components atPoint:(CGPoint)point{
NSLog(@"data -- %@",components);
}
- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url
{
NSLog(@"url -- %@",url.absoluteString);
}
- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithPhoneNumber:(NSString *)phoneNumber{
NSLog(@"number -- %@",phoneNumber);
}
注意:label.enabledTextCheckingTypes = NSTextCheckingTypePhoneNumber;这段代码主要是自动检测label.text字符串中相应类型的信息(比如NSTextCheckingTypePhoneNumber检测的是电话号码(格式一定要正确),字符串中出现的电话号码都会被添加上点击事件),点击可触发对应的委托事件;就不需要显示的调用方法:[label addLinkToPhoneNumber:@"123456" withRange:testRange];如果未设置次属性,则需要自行添加对应的点击事件。
(三)TTTAttributedLabel一些代码解析;
(1)linkAttributes属性和其他的activeLinkAttributes和inactiveLinkAttributes属性都是可配置的,linkAttributes未设置会默认的显示下划线以及blueColor的前景色;如设置了则会显示设置的样式;
(2)控件中TTTAttributedLabelDelegate的委托协议,比如[label addLinkToPhoneNumber:@"123456" withRange:testRange];点击label上的“123456”;会执行- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithPhoneNumber:(NSString *)phoneNumber对应的这个点击委托事件;为什么会执行这个委托事件呢,原因是在- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event这个点击事件中;对NSTextCheckingResult的类型进行了判断,执行对应的委托函数;
(3)下面的代码是设置label样式的函数以及执行委托判断的事件;
- (TTTAttributedLabelLink *)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result
attributes:(NSDictionary *)attributes
{
return [self addLinksWithTextCheckingResults:@[result] attributes:attributes].firstObject;
}
- (NSArray *)addLinksWithTextCheckingResults:(NSArray *)results
attributes:(NSDictionary *)attributes
{
NSMutableArray *links = [NSMutableArray array];
for (NSTextCheckingResult *result in results) {
NSDictionary *activeAttributes = attributes ? self.activeLinkAttributes : nil;
NSDictionary *inactiveAttributes = attributes ? self.inactiveLinkAttributes : nil;
TTTAttributedLabelLink *link = [[TTTAttributedLabelLink alloc] initWithAttributes:attributes
activeAttributes:activeAttributes
inactiveAttributes:inactiveAttributes
textCheckingResult:result];
[links addObject:link];
}
[self addLinks:links];
return links;
}
- (TTTAttributedLabelLink *)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result {
return [self addLinkWithTextCheckingResult:result attributes:self.linkAttributes];
}
//判断执行那个委托事件;
- (void)touchesEnded:(NSSet *)touches
withEvent:(UIEvent *)event
{
if (self.activeLink) {
if (self.activeLink.linkTapBlock) {
self.activeLink.linkTapBlock(self, self.activeLink);
self.activeLink = nil;
return;
}
NSTextCheckingResult *result = self.activeLink.result;
self.activeLink = nil;
switch (result.resultType) {
case NSTextCheckingTypeLink:
if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithURL:)]) {
[self.delegate attributedLabel:self didSelectLinkWithURL:result.URL];
return;
}
break;
case NSTextCheckingTypeAddress:
if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithAddress:)]) {
[self.delegate attributedLabel:self didSelectLinkWithAddress:result.addressComponents];
return;
}
break;
case NSTextCheckingTypePhoneNumber:
if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithPhoneNumber:)]) {
[self.delegate attributedLabel:self didSelectLinkWithPhoneNumber:result.phoneNumber];
return;
}
break;
case NSTextCheckingTypeDate:
if (result.timeZone && [self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithDate:timeZone:duration:)]) {
[self.delegate attributedLabel:self didSelectLinkWithDate:result.date timeZone:result.timeZone duration:result.duration];
return;
} else if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithDate:)]) {
[self.delegate attributedLabel:self didSelectLinkWithDate:result.date];
return;
}
break;
case NSTextCheckingTypeTransitInformation:
if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithTransitInformation:)]) {
[self.delegate attributedLabel:self didSelectLinkWithTransitInformation:result.components];
return;
}
default:
break;
}
// Fallback to `attributedLabel:didSelectLinkWithTextCheckingResult:` if no other delegate method matched.
if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithTextCheckingResult:)]) {
[self.delegate attributedLabel:self didSelectLinkWithTextCheckingResult:result];
}
} else {
[super touchesEnded:touches withEvent:event];
}
}
(四)总结;
以上只是本人对这个控件的部分代码的一些理解,也许会有理解错误的地方,希望各位技术同仁能够留言、评论指出在下错误的地方,有更好的理解也可以交流交流。