Kar*_*yan 16 xcode text ios swift swiftui
当点击文本的某些部分时,SwiftUI 中是否有任何方法可以打开浏览器。
我尝试了上述解决方案,但它不起作用,因为您无法添加的onTapGesture回报ViewText
Text("Some text ").foregroundColor(Color(UIColor.systemGray)) +
Text("clickable subtext")
.foregroundColor(Color(UIColor.systemBlue))
.onTapGesture {
}
Run Code Online (Sandbox Code Playgroud)
我想在正文中有可点击的潜台词,这就是为什么使用HStack不起作用
Але*_*кий 19
iOS 15 及更高版本的更新:
有一个新的Markdown格式支持Text,例如:
Text("Some text [clickable subtext](some url) *italic ending* ")
Run Code Online (Sandbox Code Playgroud)
iOS 13 和 14 的旧答案:
不幸的是,SwiftUI 中没有类似于 NSAttributedString 的东西。你只有几个选择。例如,在此答案中,您可以看到如何使用单击事件UIViewRepresentable创建老式学校。但现在唯一的 SwiftUI 方法是使用:UILabel HStack
Text("Some text [clickable subtext](some url) *italic ending* ")
Run Code Online (Sandbox Code Playgroud)
更新
使用UITextView和添加解决方案UIViewRepresentable。我结合了添加链接的所有内容,结果非常好,我认为:
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
UIViewRepresentable和的结果UITextView:
更新2:这是一个NSMutableAttributedString小扩展:
extension NSMutableAttributedString {
var range: NSRange {
NSRange(location: 0, length: self.length)
}
}
Run Code Online (Sandbox Code Playgroud)
从 iOS 15 开始,您可以将AttributedString和Markdown与文本一起使用。
使用示例Markdown:
Text("Plain text. [This is a tappable link](https://stackoverflow.com)")
Run Code Online (Sandbox Code Playgroud)
AttributedString让您可以更好地控制格式。例如,您可以更改链接颜色:
var string = AttributedString("Plain text. ")
var tappableText = AttributedString("I am tappable!")
tappableText.link = URL(string: "https://stackoverflow.com")
tappableText.foregroundColor = .green
string.append(tappableText)
Text(string)
Run Code Online (Sandbox Code Playgroud)
它看起来是这样的:
旁注:如果您希望可点击文本具有与在浏览器中打开 URL 不同的行为,您可以为您的应用程序定义自定义 URL 方案。然后,您将能够使用onOpenURL(perform:)注册处理程序来处理链接上的点击事件,以便在视图收到视图所在场景或窗口的 url 时调用。
我没有耐心去制作UITextView和UIViewRepresentable工作,所以我让整个段落都可以点击,但仍然保持带下划线的 URL 外观/感觉。如果您尝试将服务条款 URL 链接添加到您的应用程序,则特别有用。
代码相当简单:
Button(action: {
let tosURL = URL.init(string: "https://www.google.com")! // add your link here
if UIApplication.shared.canOpenURL(tosURL) {
UIApplication.shared.open(tosURL)
}
}, label: {
(Text("Store.ly helps you find storage units nearby. By continuing, you agree to our ")
+ Text("Terms of Service.")
.underline()
)
.frame(maxWidth: .infinity, alignment: .leading)
.font(Font.system(size: 14, weight: .medium))
.foregroundColor(Color.black)
.fixedSize(horizontal: false, vertical: true)
})
.padding([.horizontal], 20)
Run Code Online (Sandbox Code Playgroud)
小智 6
基于 Dhaval Bera 的代码,我放置了一些结构。
struct TextLabelWithHyperLink: UIViewRepresentable {
@State var tintColor: UIColor
@State var hyperLinkItems: Set<HyperLinkItem>
private var _attributedString: NSMutableAttributedString
private var openLink: (HyperLinkItem) -> Void
init (
tintColor: UIColor,
string: String,
attributes: [NSAttributedString.Key : Any],
hyperLinkItems: Set<HyperLinkItem>,
openLink: @escaping (HyperLinkItem) -> Void
) {
self.tintColor = tintColor
self.hyperLinkItems = hyperLinkItems
self._attributedString = NSMutableAttributedString(
string: string,
attributes: attributes
)
self.openLink = openLink
}
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
textView.isEditable = false
textView.isSelectable = true
textView.tintColor = self.tintColor
textView.delegate = context.coordinator
textView.isScrollEnabled = false
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
for item in hyperLinkItems {
let subText = item.subText
let link = item.subText.replacingOccurrences(of: " ", with: "_")
_attributedString
.addAttribute(
.link,
value: String(format: "https://%@", link),
range: (_attributedString.string as NSString).range(of: subText)
)
}
uiView.attributedText = _attributedString
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
class Coordinator: NSObject, UITextViewDelegate {
var parent : TextLabelWithHyperLink
init( parent: TextLabelWithHyperLink ) {
self.parent = parent
}
func textView(
_ textView: UITextView,
shouldInteractWith URL: URL,
in characterRange: NSRange,
interaction: UITextItemInteraction
) -> Bool {
let strPlain = URL.absoluteString
.replacingOccurrences(of: "https://", with: "")
.replacingOccurrences(of: "_", with: " ")
if let ret = parent.hyperLinkItems.first(where: { $0.subText == strPlain }) {
parent.openLink(ret)
}
return false
}
}
}
struct HyperLinkItem: Hashable {
let subText : String
let attributes : [NSAttributedString.Key : Any]?
init (
subText: String,
attributes: [NSAttributedString.Key : Any]? = nil
) {
self.subText = subText
self.attributes = attributes
}
func hash(into hasher: inout Hasher) {
hasher.combine(subText)
}
static func == (lhs: HyperLinkItem, rhs: HyperLinkItem) -> Bool {
lhs.hashValue == rhs.hashValue
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
TextLabelWithHyperLink(
tintColor: .green,
string: "Please contact us by filling contact form. We will contact with you shortly. Your request will be processed in accordance with the Terms of Use and Privacy Policy.",
attributes: [:],
hyperLinkItems: [
.init(subText: "processed"),
.init(subText: "Terms of Use"),
],
openLink: {
(tappedItem) in
print("Tapped link: \(tappedItem.subText)")
}
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5697 次 |
| 最近记录: |