VoiceOver doesn't work for AVRoutePickerView wrapped in UIViewRepresentable

Hi,

I've wrapped AVRoutePickerView in SwiftUI using pretty much the code given here, with a few changes:

	func makeUIView(context: Context) -> UIView {
		let routePickerView = AVRoutePickerView()


		// Configure the button's color.
		//routePickerView.delegate = context.coordinator
		//routePickerView.backgroundColor = .secondarySystemBackground
		routePickerView.tintColor = .accent
		routePickerView.activeTintColor = .accent


		// Indicate whether your app prefers video content.
		routePickerView.prioritizesVideoDevices = false

		return routePickerView
	}

I commented out routePickerView.delegate = context.coordinator because it doesn't compile; context.coordinator is of type Void and I'm not sure how to fix that. I'm not sure if that has anything to do with the issue.

Anyway, this works fine without VoiceOver; if I tap the button, I get the AirPlay popover. But in VoiceOver, if I select the button and double-tap, nothing happens… it just reads the button's accessibilityLabel again. How can I get the AirPlay popover to show in VoiceOver?

Answered by Frameworks Engineer in 851534022

Thanks for mentioning this issue. Could you please file a bug report using the Feedback Assistant tool? https://developer.apple.com/bug-reporting/

If you could reproduce the issue in a screen recording then follow the instructions in the Feedback Assistant tool to gather device diagnostics / logs, it will help us understand this issue much better.

Including code samples like the one above or any additional code samples that you feel might be relevant will also help!

You can post the Feedback ID number here once you filed it and I'll make sure it gets some attention. Thanks!

Accepted Answer

Thanks for mentioning this issue. Could you please file a bug report using the Feedback Assistant tool? https://developer.apple.com/bug-reporting/

If you could reproduce the issue in a screen recording then follow the instructions in the Feedback Assistant tool to gather device diagnostics / logs, it will help us understand this issue much better.

Including code samples like the one above or any additional code samples that you feel might be relevant will also help!

You can post the Feedback ID number here once you filed it and I'll make sure it gets some attention. Thanks!

In the process of making a minimal example to file a bug, of course I realised what I was doing that caused the issue. I am still going to file a feedback, in case someone else does this kind of weird workaround and doesn't notice that it breaks VO.

I wanted the button to be bordered, to match my other buttons, and the only way I found to do that was to have the actual button as the label of a SwiftUI button, like so:

Button() {
} label: {
					//The device picker has a lot more padding than a typical SF Symbols image, so we have to give it negative padding so that the icon and button look about the same size as the other buttons
					DevicePickerView().padding(-10).frame(width: devicePickerSize, height: devicePickerSize)
}.buttonStyle(.bordered)

With the button inside another button like this, it works fine without VoiceOver (edit: I thought it was working on macOS with VoiceOver, but I actually didn't do this weird button-in-button thing on macOS), but not on iOS with VoiceOver.

When I just use the DevicePickerView by itself, it also works on iOS with VoiceOver, but I can't figure out how to get the bordered appearance, given that routePickerButtonStyle and isRoutePickerButtonBordered are macOS only, and DevicePickerView().buttonStyle(.bordered) doesn't seem to do anything.

For now I'll just forget about the border because it's more important to have it working than looking nice. But my new question is, how can I make a bordered version of a route picker view?

Edit: I can fake it fairly well with .background(Color.secondary.opacity(0.2)).containerShape(RoundedRectangle(cornerRadius: 8)) but I don't like those magic numbers in there.

I filed bug report FB19299788 about this.

VoiceOver doesn't work for AVRoutePickerView wrapped in UIViewRepresentable
 
 
Q