Skip to content

Commit c8b6d60

Browse files
sherginfacebook-github-bot
authored andcommitted
Fabric: Custom border rendering on a separate CALayer
Summary: This diff fixes previously broken custom border rendering. We need a dedicated CALayer for border bitmap in order to fully support all UIView capabilities in case if some subclass uses that. Otherwise, any call of `drawRect:` method can override any content which is stored inside `contents` property of CALayer. Q&A: How does it work in current RN? - It does not. All `drawRect:` methods in RCTView subclasses are dysfunctional. How does text view work in current RN? - RCTTextView does not inherit RCTView, so it does not have this problem. How does text view support custom borders in current RN then? - It does not. Reviewed By: PeteTheHeat Differential Revision: D10228805 fbshipit-source-id: 22bc31f41ab1914a97f3a5981cd1b24ebca725cd
1 parent 082a869 commit c8b6d60

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

+23-14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
@implementation RCTViewComponentView
2121
{
2222
UIColor *_backgroundColor;
23+
CALayer *_borderLayer;
2324
}
2425

2526
- (instancetype)initWithFrame:(CGRect)frame
@@ -49,6 +50,10 @@ - (void)layoutSubviews
4950
{
5051
[super layoutSubviews];
5152

53+
if (_borderLayer) {
54+
_borderLayer.frame = self.layer.bounds;
55+
}
56+
5257
if (_contentView) {
5358
_contentView.frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame());
5459
}
@@ -346,15 +351,26 @@ - (void)invalidateLayer
346351
);
347352

348353
if (useCoreAnimationBorderRendering) {
349-
layer.contents = nil;
350-
layer.needsDisplayOnBoundsChange = NO;
354+
if (_borderLayer) {
355+
[_borderLayer removeFromSuperlayer];
356+
_borderLayer = nil;
357+
}
358+
351359
layer.borderWidth = (CGFloat)borderMetrics.borderWidths.left;
352360
layer.borderColor = RCTCGColorRefFromSharedColor(borderMetrics.borderColors.left);
353361
layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft;
354362
layer.backgroundColor = _backgroundColor.CGColor;
355363
_contentView.layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft;
356364
_contentView.layer.masksToBounds = YES;
357365
} else {
366+
if (!_borderLayer) {
367+
_borderLayer = [[CALayer alloc] init];
368+
_borderLayer.zPosition = -1024.0f;
369+
_borderLayer.frame = layer.bounds;
370+
_borderLayer.magnificationFilter = kCAFilterNearest;
371+
[layer addSublayer:_borderLayer];
372+
}
373+
358374
layer.backgroundColor = nil;
359375
layer.borderWidth = 0;
360376
layer.borderColor = nil;
@@ -373,8 +389,7 @@ - (void)invalidateLayer
373389
);
374390

375391
if (image == nil) {
376-
layer.contents = nil;
377-
layer.needsDisplayOnBoundsChange = NO;
392+
_borderLayer.contents = nil;
378393
} else {
379394
CGSize imageSize = image.size;
380395
UIEdgeInsets imageCapInsets = image.capInsets;
@@ -383,16 +398,14 @@ - (void)invalidateLayer
383398
CGSize {(CGFloat)1.0 / imageSize.width, (CGFloat)1.0 / imageSize.height}
384399
};
385400

386-
layer.contents = (id)image.CGImage;
387-
layer.contentsScale = image.scale;
388-
layer.needsDisplayOnBoundsChange = YES;
389-
layer.magnificationFilter = kCAFilterNearest;
401+
_borderLayer.contents = (id)image.CGImage;
402+
_borderLayer.contentsScale = image.scale;
390403

391404
const BOOL isResizable = !UIEdgeInsetsEqualToEdgeInsets(image.capInsets, UIEdgeInsetsZero);
392405
if (isResizable) {
393-
layer.contentsCenter = contentsCenter;
406+
_borderLayer.contentsCenter = contentsCenter;
394407
} else {
395-
layer.contentsCenter = CGRect { CGPoint {0.0, 0.0}, CGSize {1.0, 1.0}};
408+
_borderLayer.contentsCenter = CGRect { CGPoint {0.0, 0.0}, CGSize {1.0, 1.0}};
396409
}
397410
}
398411

@@ -420,10 +433,6 @@ - (void)invalidateLayer
420433
layer.cornerRadius = cornerRadius;
421434
layer.mask = maskLayer;
422435
}
423-
424-
// After updating `layer`'s parameters we have to redraw on top of it
425-
// all custom content (calling `drawRect:` implemented in subclasses).
426-
[layer setNeedsDisplay];
427436
}
428437

429438
#pragma mark - Accessibility

0 commit comments

Comments
 (0)