Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mimic the logic to find elements in UITableView to UICollectionview #1246

Merged
merged 1 commit into from
Nov 5, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 29 additions & 27 deletions Sources/KIF/Additions/UIView-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -303,48 +303,50 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi
} else if ([self isKindOfClass:[UICollectionView class]]) {
UICollectionView *collectionView = (UICollectionView *)self;

NSArray *indexPathsForVisibleItems = [collectionView indexPathsForVisibleItems];

NSMutableArray *indexPathsForVisibleItems = [[NSMutableArray alloc] init];
[[collectionView visibleCells] enumerateObjectsUsingBlock:^(UICollectionViewCell *cell, NSUInteger idx, BOOL *stop) {
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
if (indexPath) {
[indexPathsForVisibleItems addObject:indexPath];
}
}];

CFTimeInterval delay = 0.05;
for (NSUInteger section = 0, numberOfSections = [collectionView numberOfSections]; section < numberOfSections; section++) {
for (NSUInteger item = 0, numberOfItems = [collectionView numberOfItemsInSection:section]; item < numberOfItems; item++) {
for (NSUInteger row = 0, numberOfItems = [collectionView numberOfItemsInSection:section]; row < numberOfItems; row++) {
if (!self.window) {
break;
}

// Skip visible items because they are already handled
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
// Skip visible rows because they are already handled.
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:row inSection:section];
if ([indexPathsForVisibleItems containsObject:indexPath]) {
continue;
@autoreleasepool {
//scroll to the last row of each section before continuing. Attemps to ensure we can get to sections that are off screen. KIF tests (e.g. testButtonAbsentAfterRemoveFromSuperview) fails without this line. Also without this... we can't expose the next section (in code downstream)
[collectionView scrollToItemAtIndexPath:[indexPathsForVisibleItems lastObject] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
continue;
}
}

@autoreleasepool {
// Get the cell directly from the dataSource because UICollectionView will only vend visible cells
UICollectionViewCell *cell = [collectionView.dataSource collectionView:collectionView cellForItemAtIndexPath:indexPath];

// The cell contents might change just prior to being displayed, so we simulate the cell appearing onscreen
if ([collectionView.delegate respondsToSelector:@selector(collectionView:willDisplayCell:forItemAtIndexPath:)]) {
[collectionView.delegate collectionView:collectionView willDisplayCell:cell forItemAtIndexPath:indexPath];
}
@autoreleasepool {
// Scroll to the cell and wait for the animation to complete. Using animations here may not be optimal.
CGRect sectionRect = [collectionView layoutAttributesForItemAtIndexPath:indexPath].frame;
[collectionView scrollRectToVisible:sectionRect animated:NO];

// wait for it to scroll before checking for cell
CFRunLoopRunInMode(UIApplicationCurrentRunMode, delay, false);

UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
UIAccessibilityElement *element = [cell accessibilityElementMatchingBlock:matchBlock notHidden:NO];

// Remove the cell from the collection view so that it doesn't stick around
[cell removeFromSuperview];


// Skip this cell if it isn't the one we're looking for
// Sometimes we get cells with no size here which can cause an endless loop, so we ignore those
if (!element || CGSizeEqualToSize(cell.frame.size, CGSizeZero)) {
if (!element) {
continue;
}
}

// Scroll to the cell and wait for the animation to complete
CGRect frame = [collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath].frame;
[collectionView scrollRectToVisible:frame animated:YES];

// Note: using KIFRunLoopRunInModeRelativeToAnimationSpeed here may cause tests to stall
CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.5, false);

// Now try finding the element again
CFRunLoopRunInMode(UIApplicationCurrentRunMode, delay, false);
return [self accessibilityElementMatchingBlock:matchBlock];
}
}
Expand Down