如何替换已废弃的MobileBy.IosUIAutomation实现iOS元素定位滚动?
iOS 10+ 替代MobileBy.IosUIAutomation的元素查找与滚动方案
iOS 10及以上版本不再支持MobileBy.IosUIAutomation,取而代之的是基于XCUITest的定位与操作方案,以下是具体实现方式:
一、核心定位方式替代
直接使用XCUITest支持的定位器,无需编写复杂的UIAutomation脚本:
1. 精准文本定位
如果元素的label或name属性等于目标文本,直接用以下方式定位:
// 方式1:通过name定位(对应元素的name/label属性) WebElement listItem = element.findElement(MobileBy.name(itemText)); // 方式2:通过NSPredicate定位(支持精准匹配) WebElement listItem = element.findElement(MobileBy.iOSNsPredicateString("label == '" + itemText + "'"));
2. 模糊文本定位
如果需要忽略大小写或匹配部分文本,用NSPredicate的模糊匹配:
// 忽略大小写匹配文本 WebElement listItem = element.findElement(MobileBy.iOSNsPredicateString("label CONTAINS[c] '" + itemText + "'"));
二、滚动到元素的实现
如果元素不在当前可视区域,需要先滚动到可见,推荐两种可靠方式:
1. 使用Appium内置的滚动API
通过mobile: scroll脚本直接滚动到目标元素,这是XCUITest原生支持的方法:
// 初始化JS执行器 JavascriptExecutor js = (JavascriptExecutor) driver; HashMap<String, String> scrollParams = new HashMap<>(); // 设置滚动方向和目标元素的匹配规则 scrollParams.put("direction", "down"); scrollParams.put("predicateString", "label == '" + itemText + "'"); // 执行滚动 js.executeScript("mobile: scroll", scrollParams); // 滚动完成后定位元素 WebElement listItem = element.findElement(MobileBy.iOSNsPredicateString("label == '" + itemText + "'"));
2. 模拟触摸滚动(兼容特殊场景)
如果内置滚动API不生效,可通过触摸操作模拟手动滚动,循环直到找到元素:
TouchAction touchAction = new TouchAction(driver); Dimension screenSize = driver.manage().window().getSize(); // 滚动起始和结束坐标(屏幕下半部分向上滚动) int startX = screenSize.width / 2; int startY = (int) (screenSize.height * 0.8); int endY = (int) (screenSize.height * 0.2); WebElement listItem = null; int scrollCount = 0; // 限制滚动次数,避免无限循环 while (listItem == null && scrollCount < 10) { try { listItem = element.findElement(MobileBy.name(itemText)); } catch (NoSuchElementException e) { // 执行一次滚动 touchAction.press(PointOption.point(startX, startY)) .waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))) .moveTo(PointOption.point(startX, endY)) .release() .perform(); scrollCount++; } }
三、封装复用方法
可以把滚动+定位逻辑封装成工具方法,方便多处调用:
public WebElement findElementWithScroll(String targetText) { WebElement targetElement = null; JavascriptExecutor js = (JavascriptExecutor) driver; HashMap<String, String> scrollParams = new HashMap<>(); scrollParams.put("direction", "down"); // 模糊匹配,适配文本略有差异的场景 scrollParams.put("predicateString", "label CONTAINS[c] '" + targetText + "'"); int scrollLimit = 10; while (targetElement == null && scrollLimit > 0) { try { targetElement = driver.findElement(MobileBy.iOSNsPredicateString("label == '" + targetText + "'")); } catch (NoSuchElementException e) { js.executeScript("mobile: scroll", scrollParams); scrollLimit--; } } return targetElement; }
内容的提问来源于stack exchange,提问作者JustHuffle
相关产品推荐
相关产品推荐

