【问题标题】:How to make hyperlinks in SwiftUI如何在 SwiftUI 中创建超链接
【发布时间】:2019-09-01 08:28:07
【问题描述】:

在 Swift 中,如 here 所示,您可以使用“NSMutableAttributedString”在文本中嵌入链接。

如何使用 SwiftUI 实现这一点?

我按如下方式实现它,但这看起来不像我想要的那样。 .

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            Text("By tapping Done, you agree to the ")
            Button(action: {}) {
                Text("privacy policy")
            }
            Text(" and ")
            Button(action: {}) {
                Text("terms of service")
            }
            Text(" .")
        }
    }
}

【问题讨论】:

  • SwiftUI 尚不支持任何Attribute

标签: swiftui


【解决方案1】:

Swift 5.5 (iOS 15+)

1

Foundation 支持 Markdown。

Text("[Privacy Policy](https://example.com)")

说明

要创建链接,请将链接文本括在方括号中(例如 [Duck Duck Go]),然后紧跟在括号中的 URL 后面(例如 (https://duckduckgo.com))。

My favorite search engine is [Duck Duck Go](https://duckduckgo.com).

https://www.markdownguide.org/basic-syntax/#links


2

使用链接

用于导航到 URL 的控件。

https://developer.apple.com/documentation/swiftui/link

Link("Privacy Policy", destination: URL(string: "https://example.com")!)

【讨论】:

  • 太棒了,这对 iOS 15 真的很有帮助!
  • let str = "[Privacy Policy](https://example.com)" Text(str) // does not work.
  • 使用 iOS 15+ 时,使用 Link 元素可能会更安全(更好)。示例:Link("Privacy Policy", destination: URL(string: "https://example.com")!)
  • @Daniel 谢谢。同意并更新我的答案。但他们想在文本中嵌入链接。
  • @mahan 这里的问题是我们不能改变前景色。即使将 foregroundColor 属性添加到 Text 后,它仍然保持蓝色
【解决方案2】:

正如@mahan 提到的,这对于 iOS 15.0 及更高版本使用 markdown 语言非常有效:

Text("[Privacy Policy](https://example.com)")

但是,如果您使用 String 变量并将其放入 Text 中,它将无法正常工作。示例:

let privacyPolicyText = "Read our [Privacy Policy](https://example.com) here."
Text(privacyPolicyText) // Will not work

使用字符串变量的解决方案

原因是Text 得到了多次启蒙。那么我们如何解决这个问题呢?最简单的方法就是这样做:

let privacyPolicyText = "Read our [Privacy Policy](https://example.com) here."
Text(.init(privacyPolicyText))

结果:在此处阅读我们的Privacy Policy

【讨论】:

  • 链接(“隐私政策”,目的地:URL(字符串:“example.com")!)@jacobAhlberg
  • @Pritish 这行得通,但它是另一个组件。如果您想让超链接位于Text 组件的中间,这将不起作用。例如:“如果您想阅读更多内容,请点击 [这里]({Your Link})”。
  • @JacobAhlberg 有没有办法改变链接颜色?
  • @esp 只需使用名为.accentColorviewModifier
  • 我建议:let privacyPolicyText = AttributedString("Read our [Privacy Policy](https://example.com) here.")
【解决方案3】:

Motjaba Hosseni 是对的,到目前为止,SwiftUI 中没有任何类似于 NSAttributedString 的东西。 这应该可以暂时解决您的问题:

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("By tapping Done, you agree to the ")
            HStack(spacing: 0) {
                Button("privacy policy") {}
                Text(" and ")
                Button("terms of service") {}
                Text(".")
            }
        }
    }
}

【讨论】:

  • 只要第一个 Text() 不超过一行,它就可以工作。
  • 您现在可以在 iOS 14 和 Xcode 12 中使用 Link("Stackoverflow", destination: URL(string: "https://stackoverflow.com")!)
  • 为什么这是问题的答案?这不解决“如何使用属性字符串在 swift ui 中的文本中嵌入链接”(释义)。同时这篇文章的浏览量已经超过 7k 次,答案是这个帖子上面的评论,点赞数为 0
【解决方案4】:

UIViewRepresentable 中包装 UIKit 视图始终是一种选择。只需通过手动过程来公开您要更改的每个属性。

struct AttributedText: UIViewRepresentable {
    var attributedText: NSAttributedString

    init(_ attributedText: NSAttributedString) {
        self.attributedText = attributedText
    }

    func makeUIView(context: Context) -> UITextView {
        return UITextView()
    }

    func updateUIView(_ label: UITextView, context: Context) {
        label.attributedText = attributedText
    }
}

//usage: AttributedText(NSAttributedString())

【讨论】:

  • 这种方法的一个很大的限制似乎是 UIViewRepresentable 不能将 UITextView 的 intrinsicContentSize 传达给 SwiftUI - AttributedText 将占用它所有可用的空间,这会对 StackViews 等造成严重破坏跨度>
【解决方案5】:

我知道这有点晚了,但我使用 HTML 解决了同样的问题。 首先,我创建了一个小助手和链接模型。

struct HTMLStringView: UIViewRepresentable {
  let htmlContent: String

  func makeUIView(context: Context) -> WKWebView {
    return WKWebView()
  }

  func updateUIView(_ uiView: WKWebView, context: Context) {
    uiView.loadHTMLString(htmlContent, baseURL: nil)
  }
}

struct TextLink {
    let url: URL
    let title: String
}

接下来我创建了将 String 更改为 HTML 并将第一次出现的 @link 替换为我的可点击链接的函数。

var content = "My string with @link."
var link = TextLink(url: URL(string: "https://www.facebook.com")!, title: "Facebook")
var body: some View {
    let bodySize = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body).pointSize
    var html = "<span style=\"font: -apple-system-body; font-size:calc(\(bodySize)px + 1.0vw)\">"

    if let linkRange = content.range(of: "@link") {
        let startText = content[content.startIndex ..< linkRange.lowerBound]
        let endText = content[linkRange.upperBound ..< content.endIndex]
        html += startText
        html += "<a href=\"\(link.url.absoluteString)\">\(link.title)</a>"
        html += endText
    } else {
        html += content
    }
    
    html += "</span>"
    
    return HTMLStringView(htmlContent: html)
}

【讨论】:

    【解决方案6】:

    非常简单,例如使用 LocalizedStringKey:

    let message = "Hello, www.google.com this is just testing for hyperlinks, check this out our website https://www.apple.in thank you."
    
    Text(LocalizedStringKey(message))
    

    【讨论】:

    • 您知道您可以edit 发帖吗?我问是因为看起来你删除了一个类似的帖子,然后创建了这个。
    【解决方案7】:

    使用内置函数+,看起来很有魅力:

    import SwiftUI
    
    struct ContentView: View {
        var body: some View {
            HStack {
                Button(action: {
    
                }) {
                    Text("By tapping Done, you agree to the ")
                  + Text("privacy policy")
                      .foregroundColor(Color.blue)
                  + Text(" and ")
                  + Text("terms of service")
                      .foregroundColor(Color.blue)
                  + Text(".")
                }
                .foregroundColor(Color.black)
            }
        }
    }
    

    【讨论】:

    • 这使得整个文本都可以点击,而不仅仅是链接部分。而且在这种情况下,有 2 个链接,无法区分点击的是哪一个。
    猜你喜欢
    • 2022-06-16
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2013-03-06
    • 2011-04-15
    • 1970-01-01
    相关资源
    最近更新 更多