@@ -224,6 +224,17 @@ - (BOOL)_dtx_isTestedRegionObscured:(CGRect)testedRegion inWindowBounds:(CGRect)
224224 return [self _dtx_isRegionObscured: intersection fromTestedRegion: testedRegion percent: percent];
225225}
226226
227+ - (BOOL )_dtx_hasScrollViewAncestor {
228+ UIView* superview = self.superview ;
229+ while (superview != nil ) {
230+ if ([superview isKindOfClass: UIScrollView.class]) {
231+ return YES ;
232+ }
233+ superview = superview.superview ;
234+ }
235+ return NO ;
236+ }
237+
227238- (BOOL )_dtx_testVisibilityInRect : (CGRect)rect percent : (NSUInteger )percent
228239 error : (NSError * __strong __nullable * __nullable)error {
229240 NSString * prefix = [NSString stringWithFormat: @" View “%@ ” is not visible:" , self .dtx_shortDescription];
@@ -260,8 +271,16 @@ - (BOOL)_dtx_testVisibilityInRect:(CGRect)rect percent:(NSUInteger)percent
260271 CGRect testedRegionInWindowCoords = [windowToUse convertRect: rect fromView: self ];
261272
262273 CGRect visibleBounds = self.dtx_visibleBounds ;
263- if (CGRectIsEmpty (visibleBounds) ||
264- [self _dtx_isRegionObscured: visibleBounds fromTestedRegion: visibleBounds percent: percent]) {
274+ BOOL failsClippingCheck;
275+ if ([self _dtx_hasScrollViewAncestor ]) {
276+ CGRect rectVisiblePortion = CGRectIntersection (visibleBounds, rect);
277+ failsClippingCheck = CGRectIsEmpty (rectVisiblePortion) ||
278+ [self _dtx_isRegionObscured: rectVisiblePortion fromTestedRegion: rect percent: percent];
279+ } else {
280+ failsClippingCheck = CGRectIsEmpty (visibleBounds) ||
281+ [self _dtx_isRegionObscured: visibleBounds fromTestedRegion: visibleBounds percent: percent];
282+ }
283+ if (failsClippingCheck) {
265284 auto errorDescription = [NSString stringWithFormat: @" View is clipped by one or more of its "
266285 " superviews' bounds and does not pass visibility percent "
267286 " threshold (%lu )" , (unsigned long )percent];
0 commit comments