欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS文本实现超链接

程序员文章站 2022-04-29 17:46:02
...

Demo下载地址

在做登录或者注册页面时,都会有有类似于协议阅读的功能,左边是一个选择框是否阅读,右边是一行文本,且协议文本颜色不同。

之前在做的时候,因为一行文本就能显示全,且仅仅只是一个协议,因此博主采取的方法如下:

1、在label覆盖一个clearColor的UIButton,坐标同label大小

2、给label上添加一个UITapGestureRecognizer手势

但后期有些功能牵扯到金融以及安全问题,需要多个协议以及多行显示,这时要按之前方法去做的话,就需要截取当前文本协议长度以及位置,然后在相应位置上添加buton和手势,做起来还是相对麻烦一下。因此博主想法用文本实现超链接那种方式百度一下,找到UITextView的一个代理方法,且这种方法能将前面的勾选框也显示在富文本之前,但是自我感觉没有直接创建UIImageView或者UIButton使用起来灵活,因为我们可以将UIButton的frame放大,手指触摸面积增大

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange

PS:UILabel控件是没有这个代理方法的,因此只能创建添加UITextView。

1、首先我们要设置富文本以及添加链接

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.select = NO;
    
    [self setSubView];//设置子view
    [self setLinkText];//设置文本
}

//设置子view
- (void)setSubView{
    UIFont *linkFont = [UIFont systemFontOfSize:14.0];
    CGFloat linkW = ScreenWidth - 10*2;
    
    UITextView *linkTV = [[UITextView alloc]initWithFrame:CGRectMake(10, 100, linkW, 100)];
    self.linkTV = linkTV;
    linkTV.userInteractionEnabled = YES;
    linkTV.font = linkFont;
    linkTV.textColor = UIColorFromRGB(0x999999,1.0);
    [self.view addSubview:linkTV];
    linkTV.editable = NO;//必须禁止输入,否则点击将弹出输入键盘
    linkTV.scrollEnabled = NO;
    linkTV.delegate = self;
    linkTV.textContainerInset = UIEdgeInsetsMake(0,0, 0, 0);//文本距离边界值
}

//设置文本
- (void)setLinkText{
    NSString *linkStr = @"我已阅读《登录协议》和《注册协议》,并且还有《支付宝支付协议》、《微信支付协议》,《中国工商银行协议》、《中国银行协议》、《中国建设银行协议》、《中国农业银行协议》";
    UIFont *linkFont = [UIFont systemFontOfSize:14.0];
    CGFloat linkW = ScreenWidth - 10*2;
    CGSize linkSize = [self getAttributionHeightWithString:linkStr lineSpace:1.5 kern:1 font:linkFont width:linkW];
    self.linkTV.frame = CGRectMake(10, 100, linkW, linkSize.height);
    
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:linkStr];
    [attributedString addAttribute:NSLinkAttributeName value:@"login://" range:[[attributedString string] rangeOfString:@"《登录协议》"]];
    [attributedString addAttribute:NSLinkAttributeName value:@"register://" range:[[attributedString string] rangeOfString:@"《注册协议》"]];
    
    CGSize size = CGSizeMake(12, 12);
    UIImage *image = [UIImage imageNamed:self.select == YES ? @"selected" : @"unSelected"];
    UIGraphicsBeginImageContextWithOptions(size, false, 0);
    [image drawInRect:CGRectMake(0, 0.25, 12, 12)];
    UIImage *resizeImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
    textAttachment.image = resizeImage;
    NSMutableAttributedString *imageString = (NSMutableAttributedString *)[NSMutableAttributedString attributedStringWithAttachment:textAttachment];
    [imageString addAttribute:NSLinkAttributeName value:@"checkbox://" range:NSMakeRange(0, imageString.length)];
    [attributedString insertAttributedString:imageString atIndex:0];
//    [attributedString addAttribute:NSFontAttributeName value:linkFont range:NSMakeRange(0, attributedString.length)];
    
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    //调整行间距
    paragraphStyle.lineSpacing = 1.5;
    NSDictionary *attriDict = @{NSParagraphStyleAttributeName:paragraphStyle,NSKernAttributeName:@(1),
                                NSFontAttributeName:linkFont};
    [attributedString addAttributes:attriDict range:NSMakeRange(0, attributedString.length)];
    
    self.linkTV.attributedText = attributedString;
    self.linkTV.linkTextAttributes = @{NSForegroundColorAttributeName: [UIColor blueColor], NSUnderlineColorAttributeName: [UIColor lightGrayColor], NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};
}

/*
 *  设置行间距和字间距
 *
 *  @param string    字符串
 *  @param lineSpace 行间距
 *  @param kern      字间距
 *  @param font      字体大小
 *
 *  @return 富文本
 */
- (NSAttributedString *)getAttributedWithString:(NSString *)string WithLineSpace:(CGFloat)lineSpace kern:(CGFloat)kern font:(UIFont *)font{
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    //调整行间距
    paragraphStyle.lineSpacing = lineSpace;
    NSDictionary *attriDict = @{NSParagraphStyleAttributeName:paragraphStyle,NSKernAttributeName:@(kern),
                                NSFontAttributeName:font};
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:string attributes:attriDict];
    return attributedString;
}

/* 获取富文本的高度
 *
 * @param string    文字
 * @param lineSpace 行间距
 * @param kern      字间距
 * @param font      字体大小
 * @param width     文本宽度
 *
 * @return size
 */
- (CGSize)getAttributionHeightWithString:(NSString *)string lineSpace:(CGFloat)lineSpace kern:(CGFloat)kern font:(UIFont *)font width:(CGFloat)width {
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    paragraphStyle.lineSpacing = lineSpace;
    NSDictionary *attriDict = @{
                                NSParagraphStyleAttributeName:paragraphStyle,
                                NSKernAttributeName:@(kern),
                                NSFontAttributeName:font};
    CGSize size = [string boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attriDict context:nil].size;
    return size;
}

2、响应UITextView的代理方法,类似于UIButton的点击事件

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    if ([[URL scheme] isEqualToString:@"checkbox"]) {
        self.view.backgroundColor = [UIColor whiteColor];
        self.select = !self.select;
        [self setLinkText];//设置文本
        return NO;
    }else if ([[URL scheme] isEqualToString:@"login"]) {
        self.view.backgroundColor = [UIColor redColor];
        return NO;
    }else if ([[URL scheme] isEqualToString:@"register"]) {
        self.view.backgroundColor = [UIColor greenColor];
        return NO;
    }
    return YES;
}
效果如下:

iOS文本实现超链接

参考文章

http://www.jianshu.com/p/480db0cc7380

相关标签: 富文本 超链接