The following code is work-in-progress. Once working, the intention is that it can be used on iOS to set the accessibility order of controls on a Xamarin.Forms ContentPage using a dependency service.
I am currently hitting two problems with this. The first is a compile-time error:
CS1503: Argument 2: cannot convert from 'Foundation.NSObject[]' to 'Foundation.NSObject?'
I have commented in the code where that is reported.
The second (if I comment out the code that doesn't compile) is that when debugging in Visual Studio, VS shows the nativeViews array as containing XF renderers, not UIViews. I assume that this is some VS weirdness, but could be wrong.
Can anybody assist with either of these, particularly the compile-time error?
private IVisualElementRenderer GetRenderer(VisualElement xfVisualElement)
{
IVisualElementRenderer renderer = Platform.GetRenderer(xfVisualElement);
if (renderer == null)
{
renderer = Platform.CreateRenderer(xfVisualElement);
Platform.SetRenderer(xfVisualElement, renderer);
}
return renderer;
}
private UIView GetNativeView(VisualElement xfVisualElement)
=> GetRenderer(xfVisualElement).NativeView;
public void SetReadingOrder(VisualElement xfContainingElement, VisualElement[] xfVisualElements)
{
if (GetNativeView(xfContainingElement) is IUIAccessibilityContainer accessibilityContainer)
{
if (xfVisualElements.Length > 0)
{
NSObject[] nativeViews = new UIView[xfVisualElements.Length];
int index = 0;
foreach (VisualElement xfVisualElement in xfVisualElements)
nativeViews[index++] = GetNativeView(xfVisualElement).Self;
// The following line results in the compile-time error
// CS1503: Argument 2: cannot convert from 'Foundation.NSObject[]' to 'Foundation.NSObject?'
accessibilityContainer.SetAccessibilityElements(nativeViews);
}
else
{
accessibilityContainer.SetAccessibilityElements(null);
}
}
}
Note that if I look at the definition of UIAccessibilityContainer, it appears as follows:
namespace UIKit
{
[Protocol(Name = "UIAccessibilityContainer", WrapperType = typeof(UIAccessibilityContainerWrapper), IsInformal = true)]
[ProtocolMember(IsRequired = false, IsProperty = false, IsStatic = false, Name = "AccessibilityElementCount", Selector = "accessibilityElementCount", ReturnType = typeof(nint))]
[ProtocolMember(IsRequired = false, IsProperty = false, IsStatic = false, Name = "GetAccessibilityElementAt", Selector = "accessibilityElementAtIndex:", ReturnType = typeof(NSObject), ParameterType = new[] { typeof(nint) }, ParameterByRef = new[] { false })]
[ProtocolMember(IsRequired = false, IsProperty = false, IsStatic = false, Name = "GetIndexOfAccessibilityElement", Selector = "indexOfAccessibilityElement:", ReturnType = typeof(nint), ParameterType = new[] { typeof(NSObject) }, ParameterByRef = new[] { false })]
[ProtocolMember(IsRequired = false, IsProperty = false, IsStatic = false, Name = "GetAccessibilityElements", Selector = "accessibilityElements", ReturnType = typeof(NSObject))]
[ProtocolMember(IsRequired = false, IsProperty = false, IsStatic = false, Name = "SetAccessibilityElements", Selector = "setAccessibilityElements:", ParameterType = new[] { typeof(NSObject) }, ParameterByRef = new[] { false })]
[ProtocolMember(IsRequired = false, IsProperty = true, IsStatic = false, Name = "AccessibilityContainerType", Selector = "accessibilityContainerType", PropertyType = typeof(UIAccessibilityContainerType), GetterSelector = "accessibilityContainerType", SetterSelector = "setAccessibilityContainerType:", ArgumentSemantic = ArgumentSemantic.Assign)]
public interface IUIAccessibilityContainer : INativeObject, IDisposable
{
}
}