首页 > 解决方案 > SwiftUI 可点击的潜台词

问题描述

当点击文本的某些部分时,SwiftUI 中有什么方法可以打开浏览器。

我尝试了上述解决方案,但它不起作用,因为您无法添加的onTapGesture退货ViewText

Text("Some text ").foregroundColor(Color(UIColor.systemGray)) +
Text("clickable subtext")
   .foregroundColor(Color(UIColor.systemBlue))
   .onTapGesture {

   }

我想在正文中有可点击的潜台词,这就是为什么 usingHStack不起作用

标签: iosswiftxcodetextswiftui

解决方案


iOS 15 及更高版本的更新: 有一个新的Markdown格式支持Text,例如:

Text("Some text [clickable subtext](some url) *italic ending* ")

您可以查看带有时间码的 WWDC 会话以了解详细信息

iOS 13 和 14 的旧答案:

不幸的是,SwiftUI 中没有任何类似于 NSAttributedString 的东西。你只有几个选择。例如,在这个答案中,您可以看到如何使用click eventUIViewRepresentable创建一个老式的。但现在唯一的 SwiftUI 方法是使用:UILabel HStack

struct TappablePieceOfText: View {
    
    var body: some View {
        
        HStack(spacing: 0) {
            Text("Go to ")
                .foregroundColor(.gray)

            Text("stack overflow")
                .foregroundColor(.blue)
                .underline()
                .onTapGesture {
                    let url = URL.init(string: "https://stackoverflow.com/")
                    guard let stackOverflowURL = url, UIApplication.shared.canOpenURL(stackOverflowURL) else { return }
                    UIApplication.shared.open(stackOverflowURL)
                }
            
            Text(" and enjoy")
                .foregroundColor(.gray)
        }
        
        
    }
}

更新 添加了UITextView和的解决方案UIViewRepresentable。我结合了添加链接的所有内容,结果非常好,我认为:

import SwiftUI
import UIKit

struct TappablePieceOfText: View {
    
    var body: some View {
        TextLabelWithHyperlink()
            .frame(width: 300, height: 110)
    }
    
}

struct TextLabelWithHyperlink: UIViewRepresentable {
    
    func makeUIView(context: Context) -> UITextView {
        
        let standartTextAttributes: [NSAttributedString.Key : Any] = [
            NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20),
            NSAttributedString.Key.foregroundColor: UIColor.gray
        ]
        
        let attributedText = NSMutableAttributedString(string: "You can go to ")
        attributedText.addAttributes(standartTextAttributes, range: attributedText.range) // check extention
        
        let hyperlinkTextAttributes: [NSAttributedString.Key : Any] = [
            NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20),
            NSAttributedString.Key.foregroundColor: UIColor.blue,
            NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue,
            NSAttributedString.Key.link: "https://stackoverflow.com"
        ]
        
        let textWithHyperlink = NSMutableAttributedString(string: "stack overflow site")
        textWithHyperlink.addAttributes(hyperlinkTextAttributes, range: textWithHyperlink.range)
        attributedText.append(textWithHyperlink)
        
        let endOfAttrString = NSMutableAttributedString(string: " end enjoy it using old-school UITextView and UIViewRepresentable")
        endOfAttrString.addAttributes(standartTextAttributes, range: endOfAttrString.range)
        attributedText.append(endOfAttrString)
        
        let textView = UITextView()
        textView.attributedText = attributedText
        
        textView.isEditable = false
        textView.textAlignment = .center
        textView.isSelectable = true
        
        return textView
    }

    func updateUIView(_ uiView: UITextView, context: Context) {}
    
}

HStack和的结果TextHStack 和文本

UIViewRepresentable和的结果UITextView

在此处输入图像描述

更新2:这是一个NSMutableAttributedString小扩展:

extension NSMutableAttributedString {
    
    var range: NSRange {
        NSRange(location: 0, length: self.length)
    }
    
}

推荐阅读