为了更好地解决我在iOS上为UITests选择Picker的问题(请参阅主题here),我想编写一个“后门”方法,以编程方式选择适当的UIPicker项。
为此,我需要能够找到正在显示的UIPicker。但是,我找不到它!迭代所有UIWindows上的所有UIViews。
我找到View的代码如下:
UIView viewFound = null;
foreach (var currentWindow in UIApplication.SharedApplication.Windows)
{
viewFound = FindViewOfClass(currentWindow, typeof(UIPickerView),level);
if (viewFound != null)
{
break;
}
}
...
private static UIView FindViewOfClass(UIView view, Type classToFind, int level)
{
string message = $“{classToFind} - {level} View: + {view.GetType().ToString()}“;
Console.WriteLine(message);
if (view.GetType() == classToFind)
{
level--;
return view;
}
foreach (var item in view.Subviews)
{
level++;
return FindViewOfClass(item, classToFind,level);
}
return null;
}
但我没有看到UIPickerView - 即使它肯定显示在屏幕上。上面的代码在搜索其他视图时有效。
所以问题是 - 有没有更好的方法在当前页面上找到UIView?我找不到内置方法。
请注意,这是在iOS上的Xamarin.Forms应用程序中 - 因此存在几个额外的UI工件(就实现iOS渲染器的视图而言) - 但是,最终Picker实现为UIPickerView(我可以通过在UITest中使用'tree'命令和app.repl())。
解:
初始化pickerview时设置属性Tag。
pickerView.Tag = 1000;
View.AddSubview(pickerView);
而你通过方法ViewWithTag得到它
var picker = View.ViewWithTag(1000);
在这里查看pickerView的子视图。
来自@LandLu在Xamarin论坛上的解决方案是:
您应该首先获取当前视图控制器。然后迭代子视图以获取选择器渲染器。这是我的依赖服务,你指的是:
[assembly: Dependency(typeof(FindViewClass))]
namespace Demo.iOS
{
public class FindViewClass : IFindView
{
public void FindViewOfClass()
{
UIViewController currentViewController = topViewController();
getView(currentViewController.View);
}
List<PickerRenderer> pickerList = new List<PickerRenderer>();
void getView(UIView view)
{
if (view is PickerRenderer)
{
pickerList.Add((PickerRenderer)view);
}
else
{
foreach (UIView subView in view.Subviews)
{
getView(subView);
}
}
}
UIViewController topViewController()
{
return topViewControllerWithRootViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
}
UIViewController topViewControllerWithRootViewController(UIViewController rootViewController)
{
if (rootViewController is UITabBarController)
{
UITabBarController tabbarController = (UITabBarController)rootViewController;
return topViewControllerWithRootViewController(tabbarController.SelectedViewController);
}
else if (rootViewController is UINavigationController)
{
UINavigationController navigationController = (UINavigationController)rootViewController;
return topViewControllerWithRootViewController(navigationController.VisibleViewController);
}
else if (rootViewController.PresentedViewController != null)
{
UIViewController presentedViewController = rootViewController.PresentedViewController;
return topViewControllerWithRootViewController(presentedViewController);
}
return rootViewController;
}
}
}
完成后,我可以通过Renderer的Element属性选择我想要的索引/项目。