Accessibility

RSS for tag

Make your apps function for a broad range of users using Accessibility APIs across all Apple platforms.

Posts under Accessibility tag

130 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Voice Over accessibility: UITableView
In our app, we display contacts in UITableView. Let us say I have 300 contacts in my AddressBook, and all of them will be displayed in this table. Below this table, I have a UIButton to perform some action like invite selected contacts. With Voice Over enabled, when I get to the UITableView, it doesn't let me to proceed to the UIButton, unless I go over all 300 contacts. Is there a solution to override this and make it more friendly to the visually impaired users?
2
0
3k
Aug ’23
Issue with opening IOS Simulator
Hi, I am developing an App in React Native for this i need Xcode. However when i start my Expo Developer Tool Metro Bundler There when I click Run IOS Simulator. Always From the VS Code Terminal I am getting the same message like Xcode needs to be installed (don't worry, you won't have to use it), would you like to continue to the App Store? However I have already Xcode installed the after that when i type Y it takes me to App Store where i find the option open Xcode it's because i have already installed Xcode. Please guide me through this because i am not able to see my App on IOS devices
16
9
28k
Jul ’23
accessibilityTextHeadingLevel not working in NSAttributedString
Hey guys, I have an NSAttributedString within my app (created from HTML). I assign this string to a UITextView. I would like certain parts of that text to be marked with an 'header' accessibility trait (all the headlines in that text) so that voice over can identify them properly. I was under the impression that I can just use accessibilityTextHeadingLevel to do so, but the text in that given range is still setup with the 'text' accessibility trait: var myString = NSMutableAttributedString(...) let range = NSRange(location: 0, length: 44) myString.addAttribute(NSAttributedString.Key.accessibilityTextHeadingLevel, value: 1, range: range) How is accessibilityTextHeadingLevel supposed to work?
3
0
982
Oct ’23
Programmatically press "delete" or "cmd + v" in sandboxed app
Im working on a small text snippet / lorem ipsum app as a side project and the idea is, for instance, whenever and wherever user types "lorem10" I'd like to print/paste 10 random lorem ipsum words. Eg. "lorem10 " -> ("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do") For that to be possible I need to, Programmatically press "delete" key to remove the trigger string ("lorem10"). Programmatically press "cmd + v" for pasting the result string. This is possible, even in sandbox! But it requires accessibility permission. For instance I can simulate "delete" key press like this: func delete() {     let eventSource = CGEventSource(stateID: .combinedSessionState)     let keyDownEvent = CGEvent(       keyboardEventSource: eventSource,       virtualKey: CGKeyCode(51),       keyDown: true)     let keyUpEvent = CGEvent(       keyboardEventSource: eventSource,       virtualKey: CGKeyCode(51),       keyDown: false)     let loc = CGEventTapLocation.cghidEventTap     //Triggers system default accessibility access pop-up     keyDownEvent?.post(tap: loc)     keyUpEvent?.post(tap: loc)   } My question is essentially if this is allowed in Mac App Store? Because requesting accessibillity permission like this is not allowed in sandbox: func getPermission() { AXIsProcessTrustedWithOptions([kAXTrustedCheckOptionPrompt.takeUnretainedValue():true] as CFDictionary). } But I can simulate one short "shift" or "cmd" key press for instance, and trigger the pop-up inside a sandboxed app and get around this it seems. Is this a bug? I really hope I can release my app in the Mac App Store, but doing so I just want to be sure Im not using any bug that might get removed in the near future.
1
1
1.5k
Oct ’23
AVSpeechSynthesizer Leaking Like a Sieve
I've found multiple leaks in AVSpeechSynthesizer which are plaguing my users. My users are complaining of crashes due to this. Ive created a feedback item (FB12212129) with a sample project attached which demonstrates one of the leaks. I'm hoping an engineer notices this. The only way ive hade my feedback noticed in the past is by both creating a feedback item AND posting on the forums. So here's my forum post. Help is much appreciated!
6
5
2.9k
Oct ’23
iOS:How to code accessibility, that if user tap on the parent view then whole view should speak, if user tap the child view so only it should be speak
0 I am adding a demo code here of my problem. For this I have created a parent view in which I have 2 child views, I have added "accessibilityElement(children: .combine)" code to the parent view, which combines all the elements while I tap on the view. but I want if the user tap on the parent view then the voiceover should speak all views but if the user taps on a button, then it should separately speak the button. Requirement: If the user taps on the parent view then it should speak all the elements of the view but if the user taps on the button then it should only speak the button, not the full view again. Demo Video link: https://drive.google.com/file/d/1aOuDoTiDizQstfEHiTy-8OoGqXcD_uk0/view?usp=sharing In this video, I want if the user taps on the button it should speak only button, not the full view again. The sample code: import SwiftUI struct ContentView: View { var body: some View { VStack(alignment: .leading, spacing: 10) { topView Button("Show details") { print("Tapped show detail") }.accessibilityElement() .accessibilityLabel(Text("This is show detail")) // I want if user tap on this button separatly then it should only speak the button lable only, not the full content again. bottomView }.accessibilityElement(children: .combine) // By this code it will read the topView, button, and bottomView .padding() } @ViewBuilder private var topView: some View { VStack(alignment: .leading, spacing: 5) { Text("First Text") Text("Second Text") } } @ViewBuilder private var bottomView: some View { VStack(alignment: .leading, spacing: 5) { Text("Third Text") Text("Fourth Text") } } } Requirement: If the user taps on the parent view then it should speak all the elements but if the user taps on the button then it should only speak the button, not the full view again.
1
1
1.7k
Jul ’23
TTS problem iOS 17 beta
I see a lot of crashes on iOS 17 beta regarding some problem of "Text To Speech". Does anybody has a clue why TTS crashes? Anybody else seeing the same problem? Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x000000037f729380 Exception Codes: 0x0000000000000001, 0x000000037f729380 VM Region Info: 0x37f729380 is not in any region. Bytes after previous region: 3748828033 Bytes before following region: 52622617728 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL MALLOC_NANO 280000000-2a0000000 [512.0M] rw-/rwx SM=PRV ---> GAP OF 0xd20000000 BYTES commpage (reserved) fc0000000-1000000000 [ 1.0G] ---/--- SM=NUL ...(unallocated) Termination Reason: SIGNAL 11 Segmentation fault: 11 Terminating Process: exc handler [36389] Triggered by Thread: 9 ..... Thread 9 name: Thread 9 Crashed: 0 libobjc.A.dylib 0x000000019eeff248 objc_retain_x8 + 16 1 AudioToolboxCore 0x00000001b2da9d80 auoop::RenderPipeUser::~RenderPipeUser() + 112 (AUOOPRenderPipePool.mm:400) 2 AudioToolboxCore 0x00000001b2e110b4 -[AUAudioUnit_XPC internalDeallocateRenderResources] + 92 (AUAudioUnit_XPC.mm:904) 3 AVFAudio 0x00000001bfa4cc04 AUInterfaceBaseV3::Uninitialize() + 60 (AUInterface.mm:524) 4 AVFAudio 0x00000001bfa894bc AVAudioEngineGraph::PerformCommand(AUGraphNodeBaseV3&, AVAudioEngineGraph::ENodeCommand, void*, unsigned int) const + 772 (AVAudioEngineGraph.mm:3317) 5 AVFAudio 0x00000001bfa93550 AVAudioEngineGraph::_Uninitialize(NSError**) + 132 (AVAudioEngineGraph.mm:1469) 6 AVFAudio 0x00000001bfa4b50c AVAudioEngineImpl::Stop(NSError**) + 396 (AVAudioEngine.mm:1081) 7 AVFAudio 0x00000001bfa4b094 -[AVAudioEngine stop] + 48 (AVAudioEngine.mm:193) 8 TextToSpeech 0x00000001c70b3c5c __55-[TTSSynthesisProviderAudioEngine renderSpeechRequest:]_block_invoke + 1756 (TTSSynthesisProviderAudioEngine.m:613) 9 libdispatch.dylib 0x00000001ae4b0740 _dispatch_call_block_and_release + 32 (init.c:1519) 10 libdispatch.dylib 0x00000001ae4b2378 _dispatch_client_callout + 20 (object.m:560) 11 libdispatch.dylib 0x00000001ae4b990c _dispatch_lane_serial_drain + 748 (queue.c:3885) 12 libdispatch.dylib 0x00000001ae4ba470 _dispatch_lane_invoke + 432 (queue.c:3976) 13 libdispatch.dylib 0x00000001ae4c5074 _dispatch_root_queue_drain_deferred_wlh + 288 (queue.c:6913) 14 libdispatch.dylib 0x00000001ae4c48e8 _dispatch_workloop_worker_thread + 404 (queue.c:6507) ... Thread 9 crashed with ARM Thread State (64-bit): x0: 0x0000000283309360 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x00000002833093c0 x4: 0x00000002833093c0 x5: 0x0000000101737740 x6: 0x0000000000000013 x7: 0x00000000ffffffff x8: 0x0000000283309360 x9: 0x3c788942d067009a x10: 0x0000000101547000 x11: 0x0000000000000000 x12: 0x00000000000007fb x13: 0x00000000000007fd x14: 0x000000001ee24020 x15: 0x0000000000000020 x16: 0x0000b1037f729360 x17: 0x000000037f729360 x18: 0x0000000000000000 x19: 0x0000000000000000 x20: 0x00000001016a8de8 x21: 0x0000000283e21d00 x22: 0x0000000283b3f1f8 x23: 0x0000000283098000 x24: 0x00000001bfb4fc35 x25: 0x00000001bfb4fc43 x26: 0x000000028033a688 x27: 0x0000000280c93090 x28: 0x0000000000000000 fp: 0x000000016fc86490 lr: 0x00000001b2da9d80 sp: 0x000000016fc863e0 pc: 0x000000019eeff248 cpsr: 0x1000 esr: 0x92000006 (Data Abort) byte read Translation fault
20
2
5.8k
Jan ’24
SwiftUI Drag and Drop Accessibility
I've noticed some inconsistencies with the onDrag and onDrop modifiers. Sometimes my objects that can be reordered will announce, "Drag", and will give VoiceOver the ability to move and re-order the object. Other times the "Drag" is never announced, and therefore not accessible to VoiceOver users who may need to re-order their elements. Why does this work sometimes and other times not at all? The Accessibility Inspector is not helpful with this type of interaction so I am limited to testing this on device. Unfortunately, I do not have devices for every iOS version that we currently support (15.x.y - 16.5.z).
0
0
376
Jul ’23
UIButton not respecting maximumContentSizeCategory
I have a UIButton inside a dynamically-populated stack view that is within a self-sizing table view cell, and although it has a maximumContentSizeCategory of XXXL it is clearly not respecting that. Has anyone else run into this issue, and if so have you found a workaround? I used the appliedContentSizeCategoryLimitsDescription property described here: https://useyourloaf.com/blog/restricting-dynamic-type-sizes to confirm that the maximumContentSizeCategory is indeed being set correctly. This is in the iOS 16.2 iPhone 14 Pro simulator, running in Xcode 14.2.
4
0
920
Jul ’23
Dynamic Type and Widget Layout
I have a ToDo list app with an accompanying widget that displays upcoming items with an 'n more...' label at the bottom if they don't all fit. At the moment the number of rows is hard-coded based on widget family (4 for small and medium, 11 for large). How do I make the row count and 'more' text adjust for dynamic type sizes? Small and medium fonts should display 4 rows while large will only fit 3 before content is pushed off the bottom.
1
0
859
Jul ’23
Help customizing the accessibility of a large UICollectionView
Hello, I am turning to this forum because I suspect I am "doing it wrong" when it comes to implementing VoiceOver accessibility in my collection view. I suspect this because the system has resisted everything I have tried to do, fought it tooth and nail, and I can't see any way to get this to work. The Collection View I have a collection view that displays a large dataset. It uses a custom collection view layout to create a spreadsheet-like view. It has hundreds of rows, and each row can have hundreds of items. The items in each row do not conform to specific column widths. Their width is defined by the data they display, and for the purposes of this discussion, can be considered to be arbitrary. To the left of the "table" is a column of sticky headers whose position remains fixed in relation to the content. On top of the "table" is a row of headers, whose position also remains fixed. The Problem The default accessibility behavior that Apple has baked into UICollectionView is completely impractical for this application. Each row can contain hundreds of items, so a user who is attempting to navigate by swiping right would have to swipe through hundreds of items just to reach the second row (of hundreds). The Desired Behavior I want the user to be able to swipe through just the cells that are onscreen. To scroll, they can use the standard three-finger gesture. When scrolling occurs, VoiceOver should announce the range of data that is being displayed. Attempted Solution 1: Setting the accessibilityElements array I can set the accessibilityElements array of the UICollectionView to only contain the elements that are onscreen. I also can override the accessibilityScroll method to perform the paging upon a three-finger scroll. This works okay, but has some pretty fatal flaws: As the user swipes through elements, the collection view insists upon scrolling horizontally to try and fit the element into view. It also insists upon scrolling vertically to keep the focused element in the middle of the view. This not only causes the content offset to jump around wildly in a disorienting way, but it also brings content into view that VoiceOver does not know about because I have not added it to the accessibilityElements array. A low-vision user, or a user who pans their finger across the screen, would not be able to access those visible elements. VoiceOver refuses to read my paging announcement. No matter when I post a pageScrolled notification, the system will not read it. Setting accessibilityFrame In an attempt to fix the scroll jumping described above, I tried setting the accessibilityFrame of my collection view cells. This did nothing to alter the scroll jumping behavior, and had the added downside that, as the view jumped around, the accessibility frames did not follow it. A bridge too far? Overriding contentOffset I was about to override contentOffset on the collection view so that only I could set it. That would probably work. But it would do nothing to fix the paging announcement. Attempted Solution 2: Ignore the Cells! Use proxy UIAccessibilityElements I tried setting the accessibilityElements array of my collection view to a collection of UIAccessibilityElement instances whose accessibilityFrame matched the frame of the cells they represent. This worked pretty well! No more scrolling nonsense when swiping through cells, and my paging announcements were being read. This approach has a different, equally fatal flaw: If the user attempts to three finger-scroll too quickly, the VoiceOver process will become confused. It acts as though the last selected element is the only element that exists; swiping right or left does nothing. Three finger-scrolling also does nothing. As best as I can tell, it gets stuck with the last selected element as the only one it knows about. I have since replaced all of the elements in the collection view's accessibilityElements array and posted a layoutDidChange notification, which VoiceOver ignores completely. The only way out of this state is to tap on a cell, causing VoiceOver to refresh its collection of views that it knows about. I guess? No idea what's happening there. Now what? I'm at a complete and total loss. I'm at my wit's end. It feels like this seemingly simple customization is entirely impossible. Does anyone know what I'm doing wrong? Thanks!
2
0
1.1k
Jul ’23
Problems combining a .popover and a conditional accessibilityRepresentation
Hello friends/colleagues, I want to create a ViewModifier that accepts a conditional accessibilityIdentifier accepting an optional string input struct AccessibilityModifier: ViewModifier { let identifier: String? func body(content: Content) -> some View { if let identifier = identifier { content .accessibilityRepresentation { content .accessibilityIdentifier(identifier) } } else { content } } } it mostly works as expected, but .popover appears to be broken. For example, in the following code, the popover will work. But if I uncomment the .modifier line, the popover does not get presented struct ContentView: View { @State var isPresented: Bool = false var body: some View { VStack { Button("Show Popover") { isPresented = true } } .popover(isPresented: $isPresented) { Text("A Popover") } // .modifier(AccessibilityModifier(identifier: "a11y Modifier")) } } The popover also works when I use: .modifier(AccessibilityModifier(identifier: nil)) Any suggestions on how I can support both popovers and my conditional accessibilityIdentifier? thanks, in advance, Mike
0
0
359
Aug ’23
Issue with Accessibility Visible Text Range
I am trying to draw NSPanels on texts of other apps using AXObserverAddNotification with the attribute of kAXValueChangedNotification on an AXTextArea I need to detect if the text range on that text area is visible on the screen and I use kAXVisibleCharacterRangeAttribute to get the visible text range but it doesn't include the top bar of the app and gives a range that starts from an index that is not visible. This makes the panels drawn on top of the app's top app bar when scrolled to bottom like this gif How do I exclude the top app bar for visible text range?
1
0
297
Aug ’23