2015-03-23 20:28:42 +00:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
#import <UIKit/UIKit.h>
|
|
|
|
|
2015-04-23 15:04:16 +00:00
|
|
|
#import "RCTBridgeModule.h"
|
|
|
|
#import "RCTConvert.h"
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
#import "RCTDefines.h"
|
|
|
|
#import "RCTEventDispatcher.h"
|
2015-04-23 15:04:16 +00:00
|
|
|
#import "RCTLog.h"
|
2016-06-07 07:08:16 +00:00
|
|
|
#import "UIView+React.h"
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-03-01 23:33:55 +00:00
|
|
|
@class RCTBridge;
|
2015-02-20 04:10:52 +00:00
|
|
|
@class RCTShadowView;
|
|
|
|
@class RCTSparseArray;
|
|
|
|
@class RCTUIManager;
|
|
|
|
|
2015-11-14 18:25:00 +00:00
|
|
|
typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry);
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-03-01 23:33:55 +00:00
|
|
|
@interface RCTViewManager : NSObject <RCTBridgeModule>
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-01 23:33:55 +00:00
|
|
|
* The bridge can be used to access both the RCTUIIManager and the RCTEventDispatcher,
|
|
|
|
* allowing the manager (or the views that it manages) to manipulate the view
|
|
|
|
* hierarchy and send events back to the JS context.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2016-05-03 16:08:03 +00:00
|
|
|
@property (nonatomic, weak) RCTBridge *bridge;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This method instantiates a native view to be managed by the module. Override
|
|
|
|
* this to return a custom view instance, which may be preconfigured with default
|
|
|
|
* properties, subviews, etc. This method will be called many times, and should
|
|
|
|
* return a fresh instance each time. The view module MUST NOT cache the returned
|
|
|
|
* view and return the same instance for subsequent calls.
|
|
|
|
*/
|
2015-11-14 18:25:00 +00:00
|
|
|
- (UIView *)view;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This method instantiates a shadow view to be managed by the module. If omitted,
|
|
|
|
* an ordinary RCTShadowView instance will be created, which is typically fine for
|
|
|
|
* most view types. As with the -view method, the -shadowView method should return
|
|
|
|
* a fresh instance each time it is called.
|
|
|
|
*/
|
|
|
|
- (RCTShadowView *)shadowView;
|
|
|
|
|
|
|
|
/**
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
* DEPRECATED: declare properties of type RCTBubblingEventBlock instead
|
|
|
|
*
|
2015-08-11 13:37:12 +00:00
|
|
|
* Returns an array of names of events that can be sent by native views. This
|
|
|
|
* should return bubbling, directly-dispatched event types. The event name
|
|
|
|
* should not include a prefix such as 'on' or 'top', as this will be applied
|
|
|
|
* as needed. When subscribing to the event, use the 'Captured' suffix to
|
|
|
|
* indicate the captured form, or omit the suffix for the bubbling form.
|
2015-02-20 04:10:52 +00:00
|
|
|
*
|
|
|
|
* Note that this method is not inherited when you subclass a view module, and
|
|
|
|
* you should not call [super customBubblingEventTypes] when overriding it.
|
|
|
|
*/
|
2016-04-28 14:43:24 +00:00
|
|
|
- (NSArray<NSString *> *)customBubblingEventTypes __deprecated_msg("Use RCTBubblingEventBlock props instead.");
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-01 23:33:55 +00:00
|
|
|
* Called to notify manager that layout has finished, in case any calculated
|
|
|
|
* properties need to be copied over from shadow view to view.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-03-01 23:33:55 +00:00
|
|
|
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowView *)shadowView;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-01 23:33:55 +00:00
|
|
|
* Called after view hierarchy manipulation has finished, and all shadow props
|
|
|
|
* have been set, but before layout has been performed. Useful for performing
|
2016-06-23 10:53:50 +00:00
|
|
|
* custom layout logic or tasks that involve walking the view hierarchy.
|
2015-03-01 23:33:55 +00:00
|
|
|
* To be deprecated, hopefully.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-11-14 18:25:00 +00:00
|
|
|
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(NSDictionary<NSNumber *, RCTShadowView *> *)shadowViewRegistry;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-26 04:29:28 +00:00
|
|
|
* This handles the simple case, where JS and native property names match.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-08-06 22:44:15 +00:00
|
|
|
#define RCT_EXPORT_VIEW_PROPERTY(name, type) \
|
2015-11-03 22:45:46 +00:00
|
|
|
+ (NSArray<NSString *> *)propConfig_##name { return @[@#type]; }
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
2015-08-06 22:44:15 +00:00
|
|
|
* This macro maps a named property to an arbitrary key path in the view.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-08-06 22:44:15 +00:00
|
|
|
#define RCT_REMAP_VIEW_PROPERTY(name, keyPath, type) \
|
2015-11-03 22:45:46 +00:00
|
|
|
+ (NSArray<NSString *> *)propConfig_##name { return @[@#type, @#keyPath]; }
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-03-01 23:33:55 +00:00
|
|
|
/**
|
2015-08-06 22:44:15 +00:00
|
|
|
* This macro can be used when you need to provide custom logic for setting
|
2015-03-01 23:33:55 +00:00
|
|
|
* view properties. The macro should be followed by a method body, which can
|
|
|
|
* refer to "json", "view" and "defaultView" to implement the required logic.
|
|
|
|
*/
|
2015-03-26 04:29:28 +00:00
|
|
|
#define RCT_CUSTOM_VIEW_PROPERTY(name, type, viewClass) \
|
2015-08-06 22:44:15 +00:00
|
|
|
RCT_REMAP_VIEW_PROPERTY(name, __custom__, type) \
|
2015-03-15 23:08:42 +00:00
|
|
|
- (void)set_##name:(id)json forView:(viewClass *)view withDefaultView:(viewClass *)defaultView
|
2015-03-01 23:33:55 +00:00
|
|
|
|
2015-08-06 22:44:15 +00:00
|
|
|
/**
|
|
|
|
* This macro is used to map properties to the shadow view, instead of the view.
|
|
|
|
*/
|
|
|
|
#define RCT_EXPORT_SHADOW_PROPERTY(name, type) \
|
2015-11-03 22:45:46 +00:00
|
|
|
+ (NSArray<NSString *> *)propConfigShadow_##name { return @[@#type]; }
|
2015-03-01 23:33:55 +00:00
|
|
|
|
2016-09-26 13:11:49 +00:00
|
|
|
/**
|
|
|
|
* This macro maps a named property to an arbitrary key path in the shadow view.
|
|
|
|
*/
|
|
|
|
#define RCT_REMAP_SHADOW_PROPERTY(name, keyPath, type) \
|
|
|
|
+ (NSArray<NSString *> *)propConfigShadow_##name { return @[@#type, @#keyPath]; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This macro can be used when you need to provide custom logic for setting
|
|
|
|
* shadow view properties. The macro should be followed by a method body, which can
|
2016-09-27 10:36:32 +00:00
|
|
|
* refer to "json" and "view".
|
2016-09-26 13:11:49 +00:00
|
|
|
*/
|
|
|
|
#define RCT_CUSTOM_SHADOW_PROPERTY(name, type, viewClass) \
|
|
|
|
RCT_REMAP_SHADOW_PROPERTY(name, __custom__, type) \
|
2016-09-27 10:36:32 +00:00
|
|
|
- (void)set_##name:(id)json forShadowView:(viewClass *)view
|
2016-09-26 13:11:49 +00:00
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
@end
|