You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UITextView中为协议文本添加可点击链接并唤起SafariViewController?

实现UITextView内协议文本的点击跳转功能

嘿,这个需求我太熟了!要在UITextView里实现点击《用户协议》和《隐私政策》唤起SafariViewController打开对应链接,咱们用富文本就能轻松搞定,我给你一步步拆解:

核心思路

通过给指定文本段添加链接属性,再拦截TextView的链接点击事件,自定义打开SafariViewController,替代系统默认的外部浏览器跳转行为。

具体实现步骤(Swift版本)

  1. 导入必要框架:先导入SafariServices,用来创建内嵌的Safari浏览器页面。
  2. 构建带链接的富文本:定位到协议文本的位置,给它们添加链接属性。
  3. 配置TextView属性:关闭编辑功能,开启可选状态,设置代理以拦截点击事件。
  4. 拦截链接点击事件:实现代理方法,自定义打开SafariViewController。
import UIKit
import SafariServices

class AgreementViewController: UIViewController, UITextViewDelegate {
    
    @IBOutlet weak var agreementTextView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 基础文本内容
        let baseText = "使用本应用,即表示您同意我们的《用户协议》和《隐私政策》"
        let attributedText = NSMutableAttributedString(string: baseText)
        
        // 给《用户协议》添加链接属性
        let agreementRange = (baseText as NSString).range(of: "《用户协议》")
        attributedText.addAttribute(.link, value: "https://yourdomain.com/agreement", range: agreementRange)
        
        // 给《隐私政策》添加链接属性
        let privacyRange = (baseText as NSString).range(of: "《隐私政策》")
        attributedText.addAttribute(.link, value: "https://yourdomain.com/privacy", range: privacyRange)
        
        // 给协议文本加粗(可选,让可点击文本更醒目)
        let boldFont = UIFont.boldSystemFont(ofSize: agreementTextView.font?.pointSize ?? 16)
        attributedText.addAttribute(.font, value: boldFont, range: agreementRange)
        attributedText.addAttribute(.font, value: boldFont, range: privacyRange)
        
        // 配置TextView
        agreementTextView.attributedText = attributedText
        agreementTextView.isEditable = false
        agreementTextView.isSelectable = true
        agreementTextView.delegate = self
        // 自定义链接的颜色和下划线样式
        agreementTextView.linkTextAttributes = [
            .foregroundColor: UIColor.systemBlue,
            .underlineStyle: NSUnderlineStyle.single.rawValue
        ]
    }
    
    // 拦截链接点击,打开SafariViewController
    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        let safariVC = SFSafariViewController(url: URL)
        present(safariVC, animated: true)
        return false // 返回false阻止系统默认打开外部浏览器的行为
    }
}

Objective-C版本参考

如果你的项目是用Objective-C开发的,也可以按这个逻辑实现:

#import "AgreementViewController.h"
#import <SafariServices/SafariServices.h>

@interface AgreementViewController () <UITextViewDelegate>
@property (weak, nonatomic) IBOutlet UITextView *agreementTextView;
@end

@implementation AgreementViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *baseText = @"使用本应用,即表示您同意我们的《用户协议》和《隐私政策》";
    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:baseText];
    
    // 设置用户协议链接
    NSRange agreementRange = [baseText rangeOfString:@"《用户协议》"];
    [attributedText addAttribute:NSLinkAttributeName value:@"https://yourdomain.com/agreement" range:agreementRange];
    
    // 设置隐私政策链接
    NSRange privacyRange = [baseText rangeOfString:@"《隐私政策》"];
    [attributedText addAttribute:NSLinkAttributeName value:@"https://yourdomain.com/privacy" range:privacyRange];
    
    // 给协议文本加粗(可选)
    UIFont *boldFont = [UIFont boldSystemFontOfSize:self.agreementTextView.font.pointSize];
    [attributedText addAttribute:NSFontAttributeName value:boldFont range:agreementRange];
    [attributedText addAttribute:NSFontAttributeName value:boldFont range:privacyRange];
    
    // 配置TextView
    self.agreementTextView.attributedText = attributedText;
    self.agreementTextView.editable = NO;
    self.agreementTextView.selectable = YES;
    self.agreementTextView.delegate = self;
    
    // 自定义链接样式
    self.agreementTextView.linkTextAttributes = @{
        NSForegroundColorAttributeName: [UIColor systemBlueColor],
        NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)
    };
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction {
    SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:URL];
    [self presentViewController:safariVC animated:YES completion:nil];
    return NO;
}

@end

关键注意事项

  • 必须把isEditable设为NO,避免用户编辑文本;isSelectable要设为YES,否则无法触发链接点击事件。
  • 如果是通过Storyboard/XIB创建的TextView,记得把delegate关联到对应的ViewController。
  • 自定义样式时,除了加粗,还可以调整颜色、下划线等,让可点击文本更显眼。

内容的提问来源于stack exchange,提问作者Aleksandar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:30:42