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

SwiftUI .openURL处理末尾含下划线URL时丢失下划线问题求助

SwiftUI Text点击URL时末尾下划线丢失的解决方法

问题重现

使用SwiftUI的Text自动识别URL并通过openURL处理时,URL末尾的下划线会被截断,例如https://example.com/aaa_会被识别为https://example.com/aaa。

解决方法

方法1:用Link组件精确控制URL

放弃Text的自动URL识别,手动用Link包裹目标URL,确保传递的URL完全正确:

HStack(spacing: 4) {
    Text("Test url click ")
    Link(destination: URL(string: "https://example.com/aaa_")!) {
        Text("https://example.com/aaa_")
            .tint(.blue)
    }
}
.environment(\.openURL, OpenURLAction { url in
    print(url) // 输出正确的https://example.com/aaa_
    return .handled
})

方法2:自定义AttributedString绑定URL

通过Markdown语法显式指定链接文本和目标URL,避免自动识别的截断问题:

do {
    let attrString = try AttributedString(markdown: "Test url click [https://example.com/aaa_](https://example.com/aaa_)")
    Text(attrString)
        .environment(\.openURL, OpenURLAction { url in
            print(url) // 输出正确的URL
            return .handled
        })
        .tint(.blue)
} catch {
    Text("Test url click https://example.com/aaa_")
        .tint(.blue)
}

方法3:修正DataDetector的匹配范围

如果需要保留自动识别逻辑,可以自定义NSDataDetector的匹配规则,补全被截断的下划线:

import UIKit

func createCorrectedAttributedString(from text: String) -> AttributedString {
    let nsText = text as NSString
    let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    let matches = detector.matches(in: text, range: NSRange(location: 0, length: nsText.length))
    
    var attrString = AttributedString(text)
    for match in matches {
        guard let originalURL = match.url else { continue }
        var correctedRange = match.range
        
        // 检查匹配范围末尾是否有下划线,若有则扩展范围
        let nextIndex = correctedRange.location + correctedRange.length
        if nextIndex < nsText.length && nsText.character(at: nextIndex) == "_" {
            correctedRange.length += 1
        }
        
        let swiftRange = Range(correctedRange, in: text)!
        let correctedURLString = nsText.substring(with: correctedRange)
        attrString[swiftRange].link = URL(string: correctedURLString)
    }
    return attrString
}

// 使用示例
Text(createCorrectedAttributedString(from: "Test url click https://example.com/aaa_"))
    .environment(\.openURL, OpenURLAction { url in
        print(url)
        return .handled
    })
    .tint(.blue)

问题原因

SwiftUI的Text默认使用NSDataDetector进行URL识别,其默认规则会将末尾的下划线视为URL的非有效结尾字符,从而截断这部分内容。通过手动指定URL或修正检测范围,可以绕过这个默认限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:05:00