4

I have a UITextView and portion of the text is clickable. Link works. When I turn the accessibility feature in settings of the iPhone and turn on Voice over as well, the text of the textview is read out but the link is not working. The accessibility feature on storyboard of the textview is enabled and also link is selected under accessibility attributes and the link does not work when voice over is turned on. I have also tried adding isAccessbilityElement = true to the textview and ended up with no luck.

UITextView is added to the custom cell on a table view.

Thanks in advance for your suggestions.

XLE_22
  • 5,124
  • 3
  • 21
  • 72
SruE
  • 53
  • 1
  • 4
  • Do you mean the traits of this textview is Link and you want to voice out but nothing? – BollMose Sep 22 '16 at 08:59
  • When Voice Over accessibility is turned on the action on the link was not working. The entire text is read out but the portion of the text which is a link did not work in the sense the action on the link was not working. I added Tap gesture when VoiceOver is enabled and the link works now. – SruE Sep 28 '16 at 15:29
  • Solution found here http://stackoverflow.com/questions/39355749/is-it-possible-to-assign-an-accessibility-action-to-a-uilabel – SruE Sep 28 '16 at 15:29
  • 1
    @SruE that is not a solution to this question. This involved a UITextView. That answer is about a UILabel – Chris Apr 25 '17 at 14:46

4 Answers4

4

The problem deals with a specific VoiceOver gesture to be used when a link must be activated in a UITextView.

I created a blank project including the code snippet hereafter to get 2 URLs in the myTextView element:

class TextViewURLViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var myTextView: UITextView!

    let myString = "Follow this developers guide if you already know the VoiceOver gestures."
    let myDevURL = "https://a11y-guidelines.orange.com/mobile_EN/dev-ios.html"
    let myGesturesURL = "https://a11y-guidelines.orange.com/mobile_EN/voiceover.html"


    override func viewDidLoad() {
    
        let attributedString = NSMutableAttributedString(string: myString)

        attributedString.addAttribute(.link,
                                      value: myDevURL,
                                      range: NSRange(location: 12,
                                                     length: 17))

        attributedString.addAttribute(.link,
                                      value: myGesturesURL,
                                      range: NSRange(location: 52,
                                                     length: 19))
    
        myTextView.attributedText = attributedString
        myTextView.font = UIFont(name: myTextView.font!.fontName,
                                 size: 25.0)
    }


    func textView(_ textView: UITextView,
                  shouldInteractWith URL: URL,
                  in characterRange: NSRange,
                  interaction: UITextItemInteraction) -> Bool {
    
        UIApplication.shared.open(URL, options: [:])
        return false
    }
}

Follow the steps hereunder (iOS 12) to activate the link:

  1. Get the rotor links item with the appropriate gesture.
  2. Swipe up or down with one finger to reach the link.
  3. Double tap and hold until you see the screen on step 4.

description of the first three steps

  1. A kind of popup shows up above the link.
  2. Once the action sheet appears, flick right to get the Open action.
  3. Double tap to open the URL and get the last screen on step 7.

description of the last three steps

The only thing to remember is the double tap and hold until the popup appears above your link.

XLE_22
  • 5,124
  • 3
  • 21
  • 72
  • 1
    On iOS 16 (I'm pretty sure it's changed before 16, but my device is on 16) you don't need to double tap and hold at step 3. If you double tap the selected link, it'll open it. Double tap and hold is required if you want do see other options (it'll open the context menu). Anyway, thanks for the answer, the key is using the rotor for accessing links. Also, on iOS 16 if the attributed string contains a link, the `accessibilityTraits` property and `accessibilityHint` is automatically updated so VO will read "double tap to activate embedded link". This is problematic if you have more than one link. – Alessandro Vendruscolo Mar 16 '23 at 13:52
1

I do not have solution. I still looking for.

For now I use UIWebview in my app instead of UITextView. UIWebview is more efficient with UIAccessiblity.

Sébastien REMY
  • 2,399
  • 21
  • 39
  • 1
    This answer shouldn't be downvoted. If you have to deal with those accessibility stuff, and you are asked by business people for those requirements of which user experience is solely based on web experience, this actually the good approach. Seriously, why people would like to implement those web-like hyperlink in native ways? – superarts.org Jul 16 '18 at 19:39
1

The solution depends on the iOS version you are using. For iOS 12.* the answer https://stackoverflow.com/a/55144836/4600723 is correct.

For iOS 13+ the situation is a bit more complicated and you need to think out of the box here. I found out that setting isEditable = true and overriding the delegate method:

func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
    false
}

(to turn enditing off) will provide the behavior you are looking for.

Generally speaking, UITextView from the accessibility point of view is really buggy.

Marek Staňa
  • 522
  • 7
  • 10
0

You have to override default behaviour to select either UITextViews test or link you have provided. See this class UIAccessibilityElement. Hope this helps you

Igor Kislyuk
  • 330
  • 1
  • 4
  • 14