mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 20:15:11 +00:00
373537b281
Summary: transformMatrix only worked on iOS and there is an equivalent API that (mostly) works cross platform. decomposedMatrix could technically be passed on Android but it wasn't document and explicitly flagged as not working. My goal is to deprecate both uses and then the only supported API is the `transform: [{ matrix: ... }]` form. The only difference is that on Android the matrix gets decomposed. Currently there is some special cased magic that renames transform -> transformMatrix or decomposedMatrix depending on platform. https://github.com/facebook/react/blob/master/src/renderers/native/ReactNative/ReactNativeAttributePayload.js#L50 Therefore I'm adding an alias for both native platforms called just "transform". Next I'll swap over the JS to always target the name "transform". The only difference is how the value is marshalled over the bridge in processTransform. To do this, I have to clean up a few callers. Mostly that's just swapping to the new API. For buildInterpolator this is a bit trickier but this fixes it for all our use cases (which is only the Navigator in AdsManager). Reviewed By: vjeux Differential Revision: D3239960 fb-gh-sync-id: 838edb6644c6cdd0716834f712042f226ff3136f fbshipit-source-id: 838edb6644c6cdd0716834f712042f226ff3136f
297 lines
11 KiB
Objective-C
297 lines
11 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTViewManager.h"
|
|
|
|
#import "RCTBridge.h"
|
|
#import "RCTBorderStyle.h"
|
|
#import "RCTConvert.h"
|
|
#import "RCTEventDispatcher.h"
|
|
#import "RCTLog.h"
|
|
#import "RCTShadowView.h"
|
|
#import "RCTUIManager.h"
|
|
#import "RCTUtils.h"
|
|
#import "RCTView.h"
|
|
#import "UIView+React.h"
|
|
|
|
@implementation RCTConvert(UIAccessibilityTraits)
|
|
|
|
RCT_MULTI_ENUM_CONVERTER(UIAccessibilityTraits, (@{
|
|
@"none": @(UIAccessibilityTraitNone),
|
|
@"button": @(UIAccessibilityTraitButton),
|
|
@"link": @(UIAccessibilityTraitLink),
|
|
@"header": @(UIAccessibilityTraitHeader),
|
|
@"search": @(UIAccessibilityTraitSearchField),
|
|
@"image": @(UIAccessibilityTraitImage),
|
|
@"selected": @(UIAccessibilityTraitSelected),
|
|
@"plays": @(UIAccessibilityTraitPlaysSound),
|
|
@"key": @(UIAccessibilityTraitKeyboardKey),
|
|
@"text": @(UIAccessibilityTraitStaticText),
|
|
@"summary": @(UIAccessibilityTraitSummaryElement),
|
|
@"disabled": @(UIAccessibilityTraitNotEnabled),
|
|
@"frequentUpdates": @(UIAccessibilityTraitUpdatesFrequently),
|
|
@"startsMedia": @(UIAccessibilityTraitStartsMediaSession),
|
|
@"adjustable": @(UIAccessibilityTraitAdjustable),
|
|
@"allowsDirectInteraction": @(UIAccessibilityTraitAllowsDirectInteraction),
|
|
@"pageTurn": @(UIAccessibilityTraitCausesPageTurn),
|
|
}), UIAccessibilityTraitNone, unsignedLongLongValue)
|
|
|
|
@end
|
|
|
|
@implementation RCTViewManager
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
- (dispatch_queue_t)methodQueue
|
|
{
|
|
RCTAssert(_bridge, @"Bridge not set");
|
|
RCTAssert(_bridge.uiManager || !_bridge.valid, @"UIManager not initialized");
|
|
RCTAssert(_bridge.uiManager.methodQueue || !_bridge.valid, @"UIManager.methodQueue not initialized");
|
|
return _bridge.uiManager.methodQueue;
|
|
}
|
|
|
|
- (UIView *)view
|
|
{
|
|
return [RCTView new];
|
|
}
|
|
|
|
- (RCTShadowView *)shadowView
|
|
{
|
|
return [RCTShadowView new];
|
|
}
|
|
|
|
- (NSArray<NSString *> *)customBubblingEventTypes
|
|
{
|
|
return @[
|
|
|
|
// Generic events
|
|
@"press",
|
|
@"change",
|
|
@"focus",
|
|
@"blur",
|
|
@"submitEditing",
|
|
@"endEditing",
|
|
@"keyPress",
|
|
|
|
// Touch events
|
|
@"touchStart",
|
|
@"touchMove",
|
|
@"touchCancel",
|
|
@"touchEnd",
|
|
];
|
|
}
|
|
|
|
- (NSArray<NSString *> *)customDirectEventTypes
|
|
{
|
|
return @[];
|
|
}
|
|
|
|
- (NSDictionary<NSString *, id> *)constantsToExport
|
|
{
|
|
return @{@"forceTouchAvailable": @(RCTForceTouchAvailable())};
|
|
}
|
|
|
|
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(__unused RCTShadowView *)shadowView
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(__unused NSDictionary<NSNumber *, RCTShadowView *> *)shadowViewRegistry
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
#pragma mark - View properties
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)
|
|
RCT_EXPORT_VIEW_PROPERTY(accessibilityTraits, UIAccessibilityTraits)
|
|
RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
|
|
RCT_REMAP_VIEW_PROPERTY(accessible, isAccessibilityElement, BOOL)
|
|
RCT_REMAP_VIEW_PROPERTY(testID, accessibilityIdentifier, NSString)
|
|
RCT_REMAP_VIEW_PROPERTY(backfaceVisibility, layer.doubleSided, css_backface_visibility_t)
|
|
RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat)
|
|
RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor);
|
|
RCT_REMAP_VIEW_PROPERTY(shadowOffset, layer.shadowOffset, CGSize);
|
|
RCT_REMAP_VIEW_PROPERTY(shadowOpacity, layer.shadowOpacity, float)
|
|
RCT_REMAP_VIEW_PROPERTY(shadowRadius, layer.shadowRadius, CGFloat)
|
|
RCT_REMAP_VIEW_PROPERTY(overflow, clipsToBounds, css_clip_t)
|
|
RCT_CUSTOM_VIEW_PROPERTY(shouldRasterizeIOS, BOOL, RCTView)
|
|
{
|
|
view.layer.shouldRasterize = json ? [RCTConvert BOOL:json] : defaultView.layer.shouldRasterize;
|
|
view.layer.rasterizationScale = view.layer.shouldRasterize ? [UIScreen mainScreen].scale : defaultView.layer.rasterizationScale;
|
|
}
|
|
// TODO: t11041683 Remove this duplicate property name.
|
|
RCT_CUSTOM_VIEW_PROPERTY(transformMatrix, CATransform3D, RCTView)
|
|
{
|
|
view.layer.transform = json ? [RCTConvert CATransform3D:json] : defaultView.layer.transform;
|
|
// TODO: Improve this by enabling edge antialiasing only for transforms with rotation or skewing
|
|
view.layer.allowsEdgeAntialiasing = !CATransform3DIsIdentity(view.layer.transform);
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(transform, CATransform3D, RCTView)
|
|
{
|
|
view.layer.transform = json ? [RCTConvert CATransform3D:json] : defaultView.layer.transform;
|
|
// TODO: Improve this by enabling edge antialiasing only for transforms with rotation or skewing
|
|
view.layer.allowsEdgeAntialiasing = !CATransform3DIsIdentity(view.layer.transform);
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView)
|
|
{
|
|
if ([view respondsToSelector:@selector(setPointerEvents:)]) {
|
|
view.pointerEvents = json ? [RCTConvert RCTPointerEvents:json] : defaultView.pointerEvents;
|
|
return;
|
|
}
|
|
|
|
if (!json) {
|
|
view.userInteractionEnabled = defaultView.userInteractionEnabled;
|
|
return;
|
|
}
|
|
|
|
switch ([RCTConvert RCTPointerEvents:json]) {
|
|
case RCTPointerEventsUnspecified:
|
|
// Pointer events "unspecified" acts as if a stylesheet had not specified,
|
|
// which is different than "auto" in CSS (which cannot and will not be
|
|
// supported in `React`. "auto" may override a parent's "none".
|
|
// Unspecified values do not.
|
|
// This wouldn't override a container view's `userInteractionEnabled = NO`
|
|
view.userInteractionEnabled = YES;
|
|
case RCTPointerEventsNone:
|
|
view.userInteractionEnabled = NO;
|
|
break;
|
|
default:
|
|
RCTLogError(@"UIView base class does not support pointerEvent value: %@", json);
|
|
}
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(removeClippedSubviews, BOOL, RCTView)
|
|
{
|
|
if ([view respondsToSelector:@selector(setRemoveClippedSubviews:)]) {
|
|
view.removeClippedSubviews = json ? [RCTConvert BOOL:json] : defaultView.removeClippedSubviews;
|
|
}
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(borderRadius, CGFloat, RCTView) {
|
|
if ([view respondsToSelector:@selector(setBorderRadius:)]) {
|
|
view.borderRadius = json ? [RCTConvert CGFloat:json] : defaultView.borderRadius;
|
|
} else {
|
|
view.layer.cornerRadius = json ? [RCTConvert CGFloat:json] : defaultView.layer.cornerRadius;
|
|
}
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(borderColor, CGColor, RCTView)
|
|
{
|
|
if ([view respondsToSelector:@selector(setBorderColor:)]) {
|
|
view.borderColor = json ? [RCTConvert CGColor:json] : defaultView.borderColor;
|
|
} else {
|
|
view.layer.borderColor = json ? [RCTConvert CGColor:json] : defaultView.layer.borderColor;
|
|
}
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(borderWidth, CGFloat, RCTView)
|
|
{
|
|
if ([view respondsToSelector:@selector(setBorderWidth:)]) {
|
|
view.borderWidth = json ? [RCTConvert CGFloat:json] : defaultView.borderWidth;
|
|
} else {
|
|
view.layer.borderWidth = json ? [RCTConvert CGFloat:json] : defaultView.layer.borderWidth;
|
|
}
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(borderStyle, RCTBorderStyle, RCTView)
|
|
{
|
|
if ([view respondsToSelector:@selector(setBorderStyle:)]) {
|
|
view.borderStyle = json ? [RCTConvert RCTBorderStyle:json] : defaultView.borderStyle;
|
|
}
|
|
}
|
|
RCT_CUSTOM_VIEW_PROPERTY(hitSlop, UIEdgeInsets, RCTView)
|
|
{
|
|
if ([view respondsToSelector:@selector(setHitTestEdgeInsets:)]) {
|
|
if (json) {
|
|
UIEdgeInsets hitSlopInsets = [RCTConvert UIEdgeInsets:json];
|
|
view.hitTestEdgeInsets = UIEdgeInsetsMake(-hitSlopInsets.top, -hitSlopInsets.left, -hitSlopInsets.bottom, -hitSlopInsets.right);
|
|
} else {
|
|
view.hitTestEdgeInsets = defaultView.hitTestEdgeInsets;
|
|
}
|
|
}
|
|
}
|
|
RCT_EXPORT_VIEW_PROPERTY(onAccessibilityTap, RCTDirectEventBlock)
|
|
RCT_EXPORT_VIEW_PROPERTY(onMagicTap, RCTDirectEventBlock)
|
|
|
|
#define RCT_VIEW_BORDER_PROPERTY(SIDE) \
|
|
RCT_CUSTOM_VIEW_PROPERTY(border##SIDE##Width, CGFloat, RCTView) \
|
|
{ \
|
|
if ([view respondsToSelector:@selector(setBorder##SIDE##Width:)]) { \
|
|
view.border##SIDE##Width = json ? [RCTConvert CGFloat:json] : defaultView.border##SIDE##Width; \
|
|
} \
|
|
} \
|
|
RCT_CUSTOM_VIEW_PROPERTY(border##SIDE##Color, UIColor, RCTView) \
|
|
{ \
|
|
if ([view respondsToSelector:@selector(setBorder##SIDE##Color:)]) { \
|
|
view.border##SIDE##Color = json ? [RCTConvert CGColor:json] : defaultView.border##SIDE##Color; \
|
|
} \
|
|
}
|
|
|
|
RCT_VIEW_BORDER_PROPERTY(Top)
|
|
RCT_VIEW_BORDER_PROPERTY(Right)
|
|
RCT_VIEW_BORDER_PROPERTY(Bottom)
|
|
RCT_VIEW_BORDER_PROPERTY(Left)
|
|
|
|
#define RCT_VIEW_BORDER_RADIUS_PROPERTY(SIDE) \
|
|
RCT_CUSTOM_VIEW_PROPERTY(border##SIDE##Radius, CGFloat, RCTView) \
|
|
{ \
|
|
if ([view respondsToSelector:@selector(setBorder##SIDE##Radius:)]) { \
|
|
view.border##SIDE##Radius = json ? [RCTConvert CGFloat:json] : defaultView.border##SIDE##Radius; \
|
|
} \
|
|
} \
|
|
|
|
RCT_VIEW_BORDER_RADIUS_PROPERTY(TopLeft)
|
|
RCT_VIEW_BORDER_RADIUS_PROPERTY(TopRight)
|
|
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomLeft)
|
|
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomRight)
|
|
|
|
#pragma mark - ShadowView properties
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(backgroundColor, UIColor)
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(top, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(right, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(bottom, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(left, CGFloat);
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(width, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(height, CGFloat)
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(borderTopWidth, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(borderRightWidth, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(borderBottomWidth, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(borderLeftWidth, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(borderWidth, CGFloat)
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(marginTop, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(marginRight, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(marginBottom, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(marginLeft, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(marginVertical, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(marginHorizontal, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(margin, CGFloat)
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(paddingTop, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(paddingRight, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(paddingBottom, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(paddingLeft, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(paddingVertical, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(paddingHorizontal, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(padding, CGFloat)
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(flex, CGFloat)
|
|
RCT_EXPORT_SHADOW_PROPERTY(flexDirection, css_flex_direction_t)
|
|
RCT_EXPORT_SHADOW_PROPERTY(flexWrap, css_wrap_type_t)
|
|
RCT_EXPORT_SHADOW_PROPERTY(justifyContent, css_justify_t)
|
|
RCT_EXPORT_SHADOW_PROPERTY(alignItems, css_align_t)
|
|
RCT_EXPORT_SHADOW_PROPERTY(alignSelf, css_align_t)
|
|
RCT_EXPORT_SHADOW_PROPERTY(position, css_position_type_t)
|
|
|
|
RCT_EXPORT_SHADOW_PROPERTY(onLayout, RCTDirectEventBlock)
|
|
|
|
@end
|