I’m encountering an accessibility issue in SwiftUI related to keyboard navigation.
🐞 Problem
When using an AttributedString to display Markdown content in a SwiftUI view (such as a Text view), any links included in the Markdown are not keyboard focusable when Full Keyboard Access is enabled. This means users can’t navigate to or activate the links using the Tab key or other keyboard-only methods.
💻 Platform
- iOS version: 16+
- Framework: SwiftUI
- Device: All tested iPhones and iPads
🧪 Steps to Reproduce
- Enable Full Keyboard Access in iOS settings.
- Run the included SwiftUI Playground or equivalent app using the code below.
- Try to navigate to the link using Tab or keyboard arrow keys.
- Observe that the Markdown link is not reachable via keyboard focus.
🧩 Expected Behavior
- The Markdown link should be reachable via keyboard focus.
- It should be possible to activate the link using Space or Return.
📚 Example code
struct ContentView: View {
let attributedString: AttributedString
init() {
self.attributedString = try! AttributedString(
markdown: "This is a [test link](https://apple.com) inside an attributed string."
)
}
var body: some View {
VStack {
Text("Issue: Attributed Markdown Link Is Not Focusable with full keyboard access")
.font(.headline)
.padding()
Text(attributedString) // The link is not focusable with
.padding()
.border(Color.gray, width: 1)
Text("Expected: The link should be focusable with Full Keyboard Access.")
.foregroundColor(.red)
.padding()
}
}
}
That could be a bug, I'd greatly appreciate it if you could open a bug report, include the code snippet and post the FB number here once you do. Bug Reporting: How and Why? has tips on creating your bug report.
Using a UITextView and wrap that in a UIViewRepresentable does and you might want to consider that. For example
struct CustomTextView: UIViewRepresentable {
let attributedText: NSAttributedString
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.isEditable = false
textView.isSelectable = true
textView.isUserInteractionEnabled = true
textView.dataDetectorTypes = .link
textView.attributedText = attributedText
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
}
}