Fix hairline borders not visible (#11527)

This commit is contained in:
Oleksii Bulenok
2026-08-31 16:11:43 +02:00
committed by GitHub
parent a086a2ebe0
commit 89c8e1cb70
4 changed files with 369 additions and 329 deletions
+22
View File
@@ -403,3 +403,25 @@ index 3e48dabc6fffc246fd0517ef5f3f2b7721115511..ea4ba5fdf359c513a5ca4f0e94492fac
- }
+ auto rootShadowNodeHolder = shadowTree.getCurrentRevision().rootShadowNode;
+ const auto* rootShadowNode = rootShadowNodeHolder.get();
diff --git a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
--- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
+++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
@@ -827,9 +827,17 @@
} else {
CGSize imageSize = image.size;
UIEdgeInsets imageCapInsets = image.capInsets;
+ // The stretchable middle is whatever lies between the cap insets. The image
+ // may be larger than capInsets + 1 (its size is ceil'd to whole points), so
+ // deriving the middle from the caps rather than assuming a 1pt band keeps
+ // the bottom/right caps at their true size. A phantom cap here makes the
+ // caps overflow sub-pixel-sized layers (e.g. hairline borders), and the
+ // squeezed mesh + nearest-neighbor filtering drops the stroke entirely.
CGRect contentsCenter = CGRect{
CGPoint{imageCapInsets.left / imageSize.width, imageCapInsets.top / imageSize.height},
- CGSize{(CGFloat)1.0 / imageSize.width, (CGFloat)1.0 / imageSize.height}};
+ CGSize{
+ (imageSize.width - imageCapInsets.left - imageCapInsets.right) / imageSize.width,
+ (imageSize.height - imageCapInsets.top - imageCapInsets.bottom) / imageSize.height}};
layer.contents = (id)image.CGImage;
layer.contentsScale = image.scale;