iOS文本实现超链接

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;
}
效果如下:


参考文章

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值