Skip to content

Commit aa8d173

Browse files
authored
Merge pull request #1246 from kif-framework/derko/mimic-tableview-element-matching
Mimic the logic to find elements in UITableView to UICollectionview
2 parents 252b34e + d672576 commit aa8d173

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

Sources/KIF/Additions/UIView-KIFAdditions.m

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -303,48 +303,50 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi
303303
} else if ([self isKindOfClass:[UICollectionView class]]) {
304304
UICollectionView *collectionView = (UICollectionView *)self;
305305

306-
NSArray *indexPathsForVisibleItems = [collectionView indexPathsForVisibleItems];
307-
306+
NSMutableArray *indexPathsForVisibleItems = [[NSMutableArray alloc] init];
307+
[[collectionView visibleCells] enumerateObjectsUsingBlock:^(UICollectionViewCell *cell, NSUInteger idx, BOOL *stop) {
308+
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
309+
if (indexPath) {
310+
[indexPathsForVisibleItems addObject:indexPath];
311+
}
312+
}];
313+
314+
CFTimeInterval delay = 0.05;
308315
for (NSUInteger section = 0, numberOfSections = [collectionView numberOfSections]; section < numberOfSections; section++) {
309-
for (NSUInteger item = 0, numberOfItems = [collectionView numberOfItemsInSection:section]; item < numberOfItems; item++) {
316+
for (NSUInteger row = 0, numberOfItems = [collectionView numberOfItemsInSection:section]; row < numberOfItems; row++) {
310317
if (!self.window) {
311318
break;
312319
}
313320

314-
// Skip visible items because they are already handled
315-
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
321+
// Skip visible rows because they are already handled.
322+
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:row inSection:section];
316323
if ([indexPathsForVisibleItems containsObject:indexPath]) {
317-
continue;
324+
@autoreleasepool {
325+
//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)
326+
[collectionView scrollToItemAtIndexPath:[indexPathsForVisibleItems lastObject] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
327+
continue;
328+
}
318329
}
319-
320-
@autoreleasepool {
321-
// Get the cell directly from the dataSource because UICollectionView will only vend visible cells
322-
UICollectionViewCell *cell = [collectionView.dataSource collectionView:collectionView cellForItemAtIndexPath:indexPath];
323330

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

336+
// wait for it to scroll before checking for cell
337+
CFRunLoopRunInMode(UIApplicationCurrentRunMode, delay, false);
338+
339+
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
329340
UIAccessibilityElement *element = [cell accessibilityElementMatchingBlock:matchBlock notHidden:NO];
330-
331-
// Remove the cell from the collection view so that it doesn't stick around
332-
[cell removeFromSuperview];
333-
341+
334342
// Skip this cell if it isn't the one we're looking for
335-
// Sometimes we get cells with no size here which can cause an endless loop, so we ignore those
336-
if (!element || CGSizeEqualToSize(cell.frame.size, CGSizeZero)) {
343+
if (!element) {
337344
continue;
338345
}
339346
}
340-
341-
// Scroll to the cell and wait for the animation to complete
342-
CGRect frame = [collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath].frame;
343-
[collectionView scrollRectToVisible:frame animated:YES];
347+
344348
// Note: using KIFRunLoopRunInModeRelativeToAnimationSpeed here may cause tests to stall
345-
CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.5, false);
346-
347-
// Now try finding the element again
349+
CFRunLoopRunInMode(UIApplicationCurrentRunMode, delay, false);
348350
return [self accessibilityElementMatchingBlock:matchBlock];
349351
}
350352
}

0 commit comments

Comments
 (0)