SwiftUI中如何实现NavigationLink与Text View内联显示?
方案一:SwiftUI原生AttributedString + 导航路径控制
这种方案相对简便,利用AttributedString给指定文本添加链接标记,通过监听URL打开事件触发导航跳转,自动处理文本流式排版。
import SwiftUI struct ContentView: View { @State private var navigationPath = NavigationPath() var body: some View { NavigationStack(path: $navigationPath) { VStack { Text(createAttributedText()) .onOpenURL { url in if url.scheme == "app" && url.host == "targetpage" { navigationPath.append("Target") } } } .navigationDestination(for: String.self) { destination in if destination == "Target" { TargetView() } } } } private func createAttributedText() -> AttributedString { var baseText = AttributedString("这是一段较长的文本,其中需要将") var linkSegment = AttributedString("加粗的文本部分") linkSegment.link = URL(string: "app://targetpage") linkSegment.font = .bold(Font.body) baseText.append(linkSegment) baseText.append(AttributedString("设置为可跳转的链接,剩余文本会自动换行,保持流式排版效果,不需要手动处理布局问题。")) return baseText } } struct TargetView: View { var body: some View { Text("目标页面") .navigationTitle("跳转成功") } }
方案二:UIKit UITextView包装(灵活度更高)
如果需要自定义链接样式、点击反馈等精细控制,可以用UITextView包装成SwiftUI视图,通过代理处理点击事件。
import SwiftUI import UIKit struct LinkedTextView: UIViewRepresentable { let attributedText: NSAttributedString let onLinkTap: (URL) -> Void func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.attributedText = attributedText textView.isEditable = false textView.isSelectable = true textView.dataDetectorTypes = .link textView.delegate = context.coordinator textView.backgroundColor = .clear return textView } func updateUIView(_ uiView: UITextView, context: Context) { uiView.attributedText = attributedText } func makeCoordinator() -> Coordinator { Coordinator(onLinkTap: onLinkTap) } class Coordinator: NSObject, UITextViewDelegate { let onLinkTap: (URL) -> Void init(onLinkTap: @escaping (URL) -> Void) { self.onLinkTap = onLinkTap } func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { onLinkTap(URL) return false } } } // 使用示例 struct ContentView: View { @State private var navigationPath = NavigationPath() var body: some View { NavigationStack(path: $navigationPath) { VStack { LinkedTextView(attributedText: createNSAttributedText()) { url in if url.scheme == "app" && url.host == "targetpage" { navigationPath.append("Target") } } } .navigationDestination(for: String.self) { destination in TargetView() } } } private func createNSAttributedText() -> NSAttributedString { let baseString = NSMutableAttributedString(string: "这是一段较长的文本,其中需要将") let linkString = NSAttributedString( string: "加粗的文本部分", attributes: [ .link: URL(string: "app://targetpage")!, .font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize) ] ) baseString.append(linkString) baseString.append(NSAttributedString(string: "设置为可跳转的链接,剩余文本会自动换行,保持流式排版效果,不需要手动处理布局问题。")) return baseString } }
内容的提问来源于stack exchange,提问作者Luka Šalipur
相关产品推荐
相关产品推荐

