首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 實現富文本部分可點擊:UIWebView 方案與現代替代

     編輯:程式設計綜合問答

需求分析

需顯示一段文本,其中多處不定長子串可點擊響應事件(如超鏈接、@用戶、#話題#)。

方案對比

方案優點缺點適用場景
UIWebView + HTML 實現簡單,原生支持超鏈接、CSS 樣式 性能差,內存佔用高,iOS 12+ 棄用,App Store 審核風險 快速原型、簡單靜態富文本
UITextView + NSAttributedString 原生控件,性能好,支持自定義屬性(如 link)、長按菜單 需手動解析文本生成屬性字符串,多鏈接佈局複雜 標準 App 富文本展示
TTTAttributedLabel / ActiveLabel 開源成熟,自動檢測 URL/提及/話題,支持自定義正則 引入第三方依賴,Swift 版需橋接 社交類、評論類複雜富文本
Core Text 排版 完全控制佈局、字形、動畫,極致性能 開發難度極高,維護成本大 雜誌排版、特殊藝術字體

推薦實現:UITextView + 正則解析

- (void)configureTextViewWithText:(NSString *)text {
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:text];
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(@\\w+|#\\w+#|https?://\\S+)" options:0 error:nil];
    [regex enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
        NSRange range = result.range;
        [attrStr addAttribute:NSLinkAttributeName value:[self actionURLForRange:range] range:range];
        [attrStr addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range];
        [attrStr addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:range];
    }];
    self.textView.attributedText = attrStr;
    self.textView.delegate = self;
    self.textView.editable = NO;
    self.textView.dataDetectorTypes = UIDataDetectorTypeNone; // 禁用系統自動檢測
}

- (NSURL *)actionURLForRange:(NSRange)range {
    NSString *substring = [self.textView.text substringWithRange:range];
    // 自定義 scheme 路由,如 myapp://mention/username
    return [NSURL URLWithString:[NSString stringWithFormat:@"myapp://action?text=%@", [substring stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]]];
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction {
    // 解析 URL scheme 分發業務邏輯
    return NO; // 阻止默認打開
}

現代替代:SwiftUI + AttributedString (iOS 15+)

struct RichTextView: View {
    let text: String
    var body: some View {
        Text(parseAttributedString(text))
            .environment(\.openURL, OpenURLAction { url in
                handleCustomURL(url)
                return .handled
            })
    }
    func parseAttributedString(_ string: String) -> AttributedString {
        var attr = AttributedString(string)
        // 使用正則或 Scanner 添加 .link 屬性
        return attr
    }
}

綜上,棄用 UIWebView,優先選擇 UITextView + 正則屬性字符串,或引入 ActiveLabel 等成熟庫,兼顧性能、維護性與合規性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved