【问题标题】:UIACollectionView cells vs visibleCellsUIACollectionView 单元格与可见单元格
【发布时间】:2012-11-27 05:08:43
【问题描述】:

我正在尝试在 xcode 4.5 中使用自动化编写测试脚本。

我有一个UICollectionView,我想点击一些当前不可见的单元格。

Per documentation,我应该期望cells 返回集合视图中的所有 个单元格,而visibleCells 只返回当前可见的单元格。

相反,我看到的是单元格仅返回当前可见的单元格,并且调用 visibleCells 会在 'undefined' is not a function (evaluating 'collection.visibleCells()') 上停止脚本

var target = UIATarget.localTarget();
var collection = target.frontMostApp().mainWindow().collectionViews()[0];

UIALogger.logMessage("Looking in collection: " + collection);
UIALogger.logMessage("Cells: " + collection.cells() + " length " + collection.cells().length);
UIALogger.logMessage("Visible cells: " + collection.visibleCells());

上面的代码返回正确的UICollectionView,第二个日志行打印:

Cells: [object UIAElementArray] length 12

虽然我在集合视图中有 100 个项目,并且第三个日志行崩溃脚本。

这是文档/UIACollectionView 错误吗?

任何想法如何告诉自动化滚动直到它看到一个名为“我的单元格”的单元格? 我试过使用someCell.scrollToVisible,但我需要有单元格才能做到这一点,我没有,因为我无法从单元格中获取它。

编辑:

正如乔纳森所建议的那样,我已经实现了一个滚动直到找到的功能。 它有点特定于实现,因此您可能需要调整isCellWithName。 我还希望添加一个中断,以防我们在 while 循环中找不到所需的单元格,如果有人有想法,请随时编辑。

function isCellWithName(cell, name) {
    return (cell.staticTexts()[0].name() == name);
}

function getCellWithName(array, name) {
    for (var i = 0; i < array.length; i++) {
        if (isCellWithName(array[i], name)) {
            return array[i];
        }
    }
    return false;
}

function scrollToName(collection, name) {
    var found = getCellWithName(collection.cells(), name);
    while (found === false) {
        collection.dragInsideWithOptions({startOffset:{x:0.2, y:0.99}, endOffset:{x:0.2, y:0},duration:1.0});
        found = getCellWithName(collection.cells(), name);
    }
    return found;
}

【问题讨论】:

  • 感谢您的解决方案。效果很好。

标签: ios uiscrollview ios-ui-automation uicollectionview


【解决方案1】:

文档显然不正确。 UIACollectionView 上没有 visibleCells() 方法。我通过遍历所有集合视图元素属性并打印出它们的名称来解决这个问题:

var target = UIATarget.localTarget();
var window = target.frontMostApp().mainWindow();
var collectionView = window.collectionViews()[0];
for (var i in collectionView) {
    UIALogger.logMessage(i);
}

另一方面,表格视图元素确实使用cells() 方法列出所有单元格。我想知道他们是否因为集合视图的复杂性而选择不这样做。实际获取所有集合视图单元格、构建它们的表示和框架并返回元素(如果有很多元素)可能非常昂贵。这就是 UI 自动化在询问所有单元格的表格视图时所做的事情。为了获得元素表示,它们都必须被实例化和计算。

但是,要回答您的更大问题,如何滚动到特定单元格。您可以通过滑动手势始终将其滚动到视图中吗?这不是最方便的方法,我们被表格视图滚动到不可见元素的能力“宠坏了”。但是从用户行为测试的角度来看,滑动一定量是用户无论如何都必须要做的。测试的结构是否可以反映这一点,它会满足您的需求吗?

【讨论】:

  • 感谢您的回答,我已经为此打开了一个错误报告(id:12844375,链接:bugreport.apple.com/cgi-bin/WebObjects/RadarWeb.woa/4/wo/…
  • 我已经按照建议通过拖放添加了此功能,请参阅 EDIT to OP
  • 感谢您确认该错误 - 我们也遇到了它。 “手动”滑动可以解决这个问题,尽管这是一个令人讨厌的解决方法。
【解决方案2】:

我无法让@marmor dragInsideWithOptions() 位以通用方式工作。相反,我使用 collectionView 的 value() 函数来获取当前页面与最后一页的索引,如“第 3 页,共 11 页”。然后我使用collectionView 的scrollUp() 和scrollDown() 方法遍历页面,直到找到我们想要的。我为TuneUpuiautomation-ext.js 写了一个扩展,似乎可以解决问题,还有更多:

function animationDelay() {
    UIATarget.localTarget().delay(.2);
}

extend(UIACollectionView.prototype, {
  /**
   * Apple's bug in UIACollectionView.cells() -- only returns *visible* cells
   */

  pageCount: function() {
    var pageStatus = this.value();
    var words = pageStatus.split(" ");
    var lastPage = words[3];
    return lastPage;
  },

  currentPage: function() {
    var pageStatus = this.value();
    var words = pageStatus.split(" ");
    var currentPage = words[1];
    //var lastPage = words[3];
    return currentPage;
  },

  scrollToTop: function() {
    var current = this.currentPage();
    while (current != 1) {
        this.scrollUp();
        animationDelay();
        current = this.currentPage();
    }
  },

  scrollToBottom: function() {
    var current = this.currentPage();
    var lastPage = this.pageCount();
    while (current != lastPage) {
        this.scrollDown();
        animationDelay();
        current = this.currentPage();
    }
  },

  cellCount: function() {
    this.scrollToTop();
    var current = this.currentPage();
    var lastPage = this.pageCount();
    var cellCount = this.cells().length;
    while (current != lastPage) {
        this.scrollDown();
        animationDelay();
        current = this.currentPage();
        cellCount += this.cells().length;
    }
    return cellCount;
  },

  currentPageCellNamed: function(name) {
    var array = this.cells();
    for (var i = 0; i < array.length; i++) {
        var cell = array[i];
        if (cell.name() == name) {
            return cell;
        }
    }
    return false;
  },

  cellNamed: function(name) {
    // for performance, look on the current page first
    var foundCell = this.currentPageCellNamed(name);
    if (foundCell != false) {
        return foundCell;
    }
    if (this.currentPage() != 1) {
        // scroll up and check out the first page before we iterate
        this.scrollToTop();
        foundCell = this.currentPageCellNamed(name);
        if (foundCell != false) {
            return foundCell;
        }
    }

    var current = this.currentPage();
    var lastPage = this.pageCount();
    while (current != lastPage) {
        this.scrollDown();
        animationDelay();
        current = this.currentPage();

        foundCell = this.currentPageCellNamed(name);
        if (foundCell != false) {
            return foundCell;
        }
    }
    return false;
  },

  /**
   * Asserts that this collection view has a cell with the name (accessibility identifier)
   * matching the given +name+ argument.
   */
  assertCellNamed: function(name) {
    assertNotNull(this.cellNamed(name), "No collection cell found named '" + name + "'");
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多