Post

Replies

Boosts

Views

Activity

Reply to accessibilityElements excludes the unlisted subviews – How to Fix?
@Frameworks Engineer I have a UITableView inside a UIViewController that is embedded in a UINavigationController. I’ve added a button to navigationItem.rightBarButtonItem. By default, VoiceOver focuses on the right bar button before reading the table view content. But I’d like to change the order so that VoiceOver first goes through all table view cells and only then focuses on the right bar button. A few questions: Is there a way to customize the VoiceOver navigation order to achieve this behavior? From which element’s accessibilityElements property can I inspect the current focus order?
Apr ’25
Reply to Best Way to Navigate to the Top Element Using VoiceOver
@Frameworks Engineer On iPhone/iPad, the VoiceOver cursor ficus the item under the my finger when performing a press and hold. However, on Mac, if I’m using only keyboard navigation, how can I achieve the same behavior? Is there an optimized way to navigate directly to the Done button without manually moving through all elements? Any suggestions would be greatly appreciated!
Mar ’25
Reply to How to Receive Callbacks for UIAccessibilityAction Methods Like accessibilityPerformMagicTap()?
@Frameworks Engineer Settings > Accessibility > VoiceOver > Commands > Touch Gestures > Magic Tap The default two-finger double tap is assigned to the Magic Tap gesture, and it works as expected in first-party apps like the Clock and Podcasts apps. However, it doesn’t seem to work in my app. Below, I’ve attached a sample code for reference. Strangely, when I perform the Magic Tap in my app, it starts playing a podcast instead. import UIKit class SecondaryVC : UIViewController{ private var actionButton : UIButton = { let button = UIButton(type: .system) button.backgroundColor = .systemGreen button.setTitle("Add", for: .normal) button.layer.cornerRadius = 8 return button }() init(){ super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad(){ super.viewDidLoad() view.backgroundColor = .systemTeal addSubViews() } override class func accessibilityPerformMagicTap() -> Bool { print(">>>> SecondaryVC accessibilityPerformMagicTap") return true } override class func accessibilityPerformEscape() -> Bool { print(">>>> secodaryVC EscapeAction") return true } override class func accessibilityDecrement() { print(">>>> accessibilityDecrement") } override class func accessibilityIncrement() { print(">>>> accessibilityIncrement") } private func addSubViews(){ view.addSubview(actionButton) actionButton.translatesAutoresizingMaskIntoConstraints = false actionButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 16).isActive = true actionButton.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 16).isActive = true actionButton.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -16).isActive = true } }
Mar ’25
Reply to Exploring VoiceOver Accessibility for UITableView
@Frameworks Engineer To minimize swipes, I wrapped all elements into a single accessibility element in UITableViewCell and used UIAccessibilityCustomAction to trigger the button’s action.However, the issue arises when this button interaction needs to display a menu. Since the menu cannot be triggered programmatically, how can I achieve this ? Some articles mention that wrapping all visible elements into a single accessibility element is not a good practice. This is because VoiceOver users are not always completely blind, many have partial vision and may try to focus on specific elements individually. If everything is grouped into one element, it can make navigation feel restrictive.I’d love to hear your thoughts on this ,what’s the best approach to balance accessibility and usability in such cases?
Mar ’25
Reply to Struggling with async/await: Fetching an image off the main thread
Hey Quinn, @DTS Engineer My bad—initially, I wrote the entire code in the view controller to simplify things (yes, I know, Massive View Controller is not a great practice! LOL). I’ve now restructured the code using a simple VIPER architecture. The Actual Goal: I want to fetch data from a server off the main thread, including any data conversion needed for the UI, and then update the UI before and after the fetch. How I Structured It: • The dataTask is triggered inside the interactor’s async fetchListData() function. • In the presenter (which is a class, not an actor), I call fetchListData() using Task. However, since Task doesn’t inherit an actor context, after an await suspension point, it might resume on a different thread. To handle this, I annotated my presenter method with @MainActor to ensure UI updates happen on the main thread. My Questions: Is using @MainActor in the Task the best practice? Or should I make my entire presenter a MainActor? If I use @MainActor in the presenter, will the interactor’s fetchListData() always be executed off the main thread? I don’t want to overload the main thread with network calls or data conversion. Is there a way to ensure that the interactor always returns values on the main thread so that I don’t need to rely on @MainActor annotations in the presenter? Git repo : https://github.com/praveeniroh/AsynAwaitTest
Topic: Programming Languages SubTopic: Swift Tags:
Dec ’24