Skip to content

Commit

Permalink
🐛 Guard against an invalid view rect in screen capture
Browse files Browse the repository at this point in the history
  • Loading branch information
iujames committed Dec 19, 2023
1 parent 2003737 commit feaba6f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,18 +192,25 @@ internal extension UIView {
return subview.asViewElement(in: bounds, safeAreaInsets: childInsets, autoTag: childAutoTag)
}

// only create a selector for elements that have at least the center point
// visible in the current screen bounds, inset by any safe area adjustments
// find the rect of the visible area of the view within the safe area
let safeBounds = bounds.inset(by: safeAreaInsets)
let centerPointVisible = safeBounds.contains(CGPoint(x: absolutePosition.midX, y: absolutePosition.midY))
let visibleRect = safeBounds.intersection(absolutePosition)

// if there is no visible rect, fall back to the absolute position, but we will
// not generate any selector for non-visible item below. Do not skip the item entirely
// since it could have children that are within the visible range (out of bounds of parent)
let locationRect = visibleRect.isNull ? absolutePosition : visibleRect

// only create a selector for elements that have at least the center point
// visible in the current screen bounds, inset by any safe area adjustments
let centerPointVisible = safeBounds.contains(CGPoint(x: absolutePosition.midX, y: absolutePosition.midY))
let selector = centerPointVisible ? getAppcuesSelector(autoTag: autoTag) : nil

return AppcuesViewElement(
x: visibleRect.origin.x,
y: visibleRect.origin.y,
width: visibleRect.width,
height: visibleRect.height,
x: locationRect.origin.x,
y: locationRect.origin.y,
width: locationRect.width,
height: locationRect.height,
type: displayType,
selector: selector,
children: children.isEmpty ? nil : children,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,11 @@ class AppcuesTargetElementTraitTests: XCTestCase {
// Arrange
try XCTUnwrap(Appcues.elementTargeting as? UIKitElementTargeting).window = window

// tab bar needs to be inside the safe area
let tabBarView = UITabBar()
let tabBarButton1 = UITabBarButton()
let tabBarButton2 = UITabBarButton()
// this button is inside the tab bar
let tabBarButton3 = UITabBarButton(frame: CGRect(x: 10, y: 100, width: 40, height: 40))
tabBarView.addSubview(tabBarButton1)
tabBarView.addSubview(tabBarButton2)
Expand All @@ -311,6 +313,7 @@ class AppcuesTargetElementTraitTests: XCTestCase {
XCTAssertEqual(metadataUpdates.count, 1)
let latestMetadata = try XCTUnwrap(metadataUpdates.last)

// the rect here is x/y positioned relative to button 3 offset within the tab bar frame
XCTAssertEqual(latestMetadata["targetRectangle"], CGRect(x: 10, y: 100, width: 40, height: 40))
}
}
Expand Down

0 comments on commit feaba6f

Please sign in to comment.