UIACollectionView cells vs visibleCells

若如初见. 提交于 2019-12-04 09:02:26

The documentation is apparently incorrect. There is no visibleCells() method on UIACollectionView. I figured this out by looping over all the collection view elements properties and printing out their names:

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

Table view elements, on the other hand, do list all the cells with the cells() method. I'm wondering if they choose not to do this because of the much more complicated nature of collection views. It could be very expensive to actually fetch all the collection view cells, build their representations and frames, and return the elements if you had a lot of them. That's what UI Automation does when it asks table views for all the cells. They have to all be instantiated and calculated in order to get the element representations.

But, to answer your larger question, how to scroll to a specific cell. Can you consistently scroll it into view with a swipe gesture? It's not the most convenient way to do it and we're "spoiled" by the ability to scroll to non-visible elements with table views. But from a user behavior testing standpoint, swiping a certain amount is what the user would have to do anyway. Could the test be structured to reflect this and would it address your need?

I couldn't get the the @marmor dragInsideWithOptions() bit to work in a generic fashion. Instead, I'm using the collectionView's value() function to get an index of the current page vs. last page, as in "page 3 of 11". Then I use collectionView's scrollUp() and scrollDown() methods to walk through the pages until we find what we're after. I wrote an extension for TuneUp's uiautomation-ext.js that seem to do the trick, and more:

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 + "'");
  }
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!