Fabric: ScrollView events
Summary: Note: Some features are not suported yet, e.g. event throttling. Reviewed By: fkgozali Differential Revision: D8082771 fbshipit-source-id: d60f6e9011283aeee7aff77dc9178e99f06deb5c
This commit is contained in:
parent
20645681d1
commit
21189be7cb
|
@ -11,6 +11,7 @@
|
||||||
#import <fabric/graphics/Geometry.h>
|
#import <fabric/graphics/Geometry.h>
|
||||||
#import <fabric/scrollview/ScrollViewLocalData.h>
|
#import <fabric/scrollview/ScrollViewLocalData.h>
|
||||||
#import <fabric/scrollview/ScrollViewProps.h>
|
#import <fabric/scrollview/ScrollViewProps.h>
|
||||||
|
#import <fabric/scrollview/ScrollViewEventHandlers.h>
|
||||||
|
|
||||||
#import "RCTConversions.h"
|
#import "RCTConversions.h"
|
||||||
#import "RCTEnhancedScrollView.h"
|
#import "RCTEnhancedScrollView.h"
|
||||||
|
@ -44,6 +45,8 @@ using namespace facebook::react;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - ComponentViewProtocol
|
||||||
|
|
||||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||||
{
|
{
|
||||||
[super updateProps:props oldProps:oldProps];
|
[super updateProps:props oldProps:oldProps];
|
||||||
|
@ -104,8 +107,6 @@ using namespace facebook::react;
|
||||||
_scrollView.contentSize = contentSize;
|
_scrollView.contentSize = contentSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - ComponentViewProtocol
|
|
||||||
|
|
||||||
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView
|
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView
|
||||||
index:(NSInteger)index
|
index:(NSInteger)index
|
||||||
{
|
{
|
||||||
|
@ -119,4 +120,62 @@ using namespace facebook::react;
|
||||||
[childComponentView removeFromSuperview];
|
[childComponentView removeFromSuperview];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (ScrollViewMetrics)_scrollViewMetrics
|
||||||
|
{
|
||||||
|
ScrollViewMetrics metrics;
|
||||||
|
metrics.contentSize = RCTSizeFromCGSize(_scrollView.contentSize);
|
||||||
|
metrics.contentOffset = RCTPointFromCGPoint(_scrollView.contentOffset);
|
||||||
|
metrics.contentInset = RCTEdgeInsetsFromUIEdgeInsets(_scrollView.contentInset);
|
||||||
|
metrics.containerSize = RCTSizeFromCGSize(_scrollView.bounds.size);
|
||||||
|
metrics.zoomScale = _scrollView.zoomScale;
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - UIScrollViewDelegate
|
||||||
|
|
||||||
|
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onScroll([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onScroll([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onScrollBeginDrag([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onScrollEndDrag([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onMomentumScrollBegin([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onMomentumScrollEnd([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onMomentumScrollEnd([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onScrollBeginDrag([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale
|
||||||
|
{
|
||||||
|
std::static_pointer_cast<const ScrollViewEventHandlers>(_eventHandlers)->onScrollEndDrag([self _scrollViewMetrics]);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -21,6 +21,10 @@ inline CGRect RCTCGRectFromRect(facebook::react::Rect rect) {
|
||||||
return {RCTCGPointFromPoint(rect.origin), RCTCGSizeFromSize(rect.size)};
|
return {RCTCGPointFromPoint(rect.origin), RCTCGSizeFromSize(rect.size)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline UIEdgeInsets RCTUIEdgeInsetsFromEdgeInsets(facebook::react::EdgeInsets edgeInsets) {
|
||||||
|
return {edgeInsets.top, edgeInsets.left, edgeInsets.bottom, edgeInsets.right};
|
||||||
|
}
|
||||||
|
|
||||||
inline facebook::react::Point RCTPointFromCGPoint(CGPoint point) {
|
inline facebook::react::Point RCTPointFromCGPoint(CGPoint point) {
|
||||||
return {point.x, point.y};
|
return {point.x, point.y};
|
||||||
}
|
}
|
||||||
|
@ -32,3 +36,7 @@ inline facebook::react::Size RCTSizeFromCGSize(CGSize size) {
|
||||||
inline facebook::react::Rect RCTRectFromCGRect(CGRect rect) {
|
inline facebook::react::Rect RCTRectFromCGRect(CGRect rect) {
|
||||||
return {RCTPointFromCGPoint(rect.origin), RCTSizeFromCGSize(rect.size)};
|
return {RCTPointFromCGPoint(rect.origin), RCTSizeFromCGSize(rect.size)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline facebook::react::EdgeInsets RCTEdgeInsetsFromUIEdgeInsets(UIEdgeInsets edgeInsets) {
|
||||||
|
return {edgeInsets.top, edgeInsets.left, edgeInsets.bottom, edgeInsets.right};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ScrollViewEventHandlers.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
void ScrollViewEventHandlers::onScroll(const ScrollViewMetrics &scrollViewMetrics) const {
|
||||||
|
dispatchScrollViewEvent("scroll", scrollViewMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollViewEventHandlers::onScrollBeginDrag(const ScrollViewMetrics &scrollViewMetrics) const {
|
||||||
|
dispatchScrollViewEvent("scrollBeginDrag", scrollViewMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollViewEventHandlers::onScrollEndDrag(const ScrollViewMetrics &scrollViewMetrics) const {
|
||||||
|
dispatchScrollViewEvent("scrollEndDrag", scrollViewMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollViewEventHandlers::onMomentumScrollBegin(const ScrollViewMetrics &scrollViewMetrics) const {
|
||||||
|
dispatchScrollViewEvent("momentumScrollBegin", scrollViewMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollViewEventHandlers::onMomentumScrollEnd(const ScrollViewMetrics &scrollViewMetrics) const {
|
||||||
|
dispatchScrollViewEvent("momentumScrollEnd", scrollViewMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollViewEventHandlers::dispatchScrollViewEvent(const std::string &name, const ScrollViewMetrics &scrollViewMetrics, const folly::dynamic &payload) const {
|
||||||
|
folly::dynamic compoundPayload = folly::dynamic::object();
|
||||||
|
|
||||||
|
compoundPayload["contentOffset"] = folly::dynamic::object
|
||||||
|
("x", scrollViewMetrics.contentOffset.x)
|
||||||
|
("y", scrollViewMetrics.contentOffset.y);
|
||||||
|
|
||||||
|
compoundPayload["contentInset"] = folly::dynamic::object
|
||||||
|
("top", scrollViewMetrics.contentInset.top)
|
||||||
|
("left", scrollViewMetrics.contentInset.left)
|
||||||
|
("bottom", scrollViewMetrics.contentInset.bottom)
|
||||||
|
("right", scrollViewMetrics.contentInset.right);
|
||||||
|
|
||||||
|
compoundPayload["contentSize"] = folly::dynamic::object
|
||||||
|
("width", scrollViewMetrics.contentSize.width)
|
||||||
|
("height", scrollViewMetrics.contentSize.height);
|
||||||
|
|
||||||
|
compoundPayload["layoutMeasurement"] = folly::dynamic::object
|
||||||
|
("width", scrollViewMetrics.containerSize.width)
|
||||||
|
("height", scrollViewMetrics.containerSize.height);
|
||||||
|
|
||||||
|
compoundPayload["zoomScale"] = scrollViewMetrics.zoomScale;
|
||||||
|
|
||||||
|
if (!payload.isNull()) {
|
||||||
|
compoundPayload.merge_patch(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchEvent(name, compoundPayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <fabric/graphics/Geometry.h>
|
||||||
|
#include <fabric/core/EventHandlers.h>
|
||||||
|
#include <fabric/view/ViewEventHandlers.h>
|
||||||
|
|
||||||
|
#include <folly/dynamic.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class ScrollViewMetrics {
|
||||||
|
public:
|
||||||
|
Size contentSize;
|
||||||
|
Point contentOffset;
|
||||||
|
EdgeInsets contentInset;
|
||||||
|
Size containerSize;
|
||||||
|
Float zoomScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScrollViewEventHandlers;
|
||||||
|
|
||||||
|
using SharedScrollViewEventHandlers = std::shared_ptr<const ScrollViewEventHandlers>;
|
||||||
|
|
||||||
|
class ScrollViewEventHandlers:
|
||||||
|
public ViewEventHandlers {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using ViewEventHandlers::ViewEventHandlers;
|
||||||
|
|
||||||
|
void onScroll(const ScrollViewMetrics &scrollViewMetrics) const;
|
||||||
|
void onScrollBeginDrag(const ScrollViewMetrics &scrollViewMetrics) const;
|
||||||
|
void onScrollEndDrag(const ScrollViewMetrics &scrollViewMetrics) const;
|
||||||
|
void onMomentumScrollBegin(const ScrollViewMetrics &scrollViewMetrics) const;
|
||||||
|
void onMomentumScrollEnd(const ScrollViewMetrics &scrollViewMetrics) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void dispatchScrollViewEvent(const std::string &name, const ScrollViewMetrics &scrollViewMetrics, const folly::dynamic &payload = {}) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
|
@ -33,7 +33,7 @@ void ScrollViewShadowNode::updateLocalData() {
|
||||||
#pragma mark - LayoutableShadowNode
|
#pragma mark - LayoutableShadowNode
|
||||||
|
|
||||||
void ScrollViewShadowNode::layout(LayoutContext layoutContext) {
|
void ScrollViewShadowNode::layout(LayoutContext layoutContext) {
|
||||||
ConcreteViewShadowNode<ScrollViewProps>::layout(layoutContext);
|
ConcreteViewShadowNode::layout(layoutContext);
|
||||||
updateLocalData();
|
updateLocalData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <fabric/core/LayoutContext.h>
|
#include <fabric/core/LayoutContext.h>
|
||||||
|
#include <fabric/scrollview/ScrollViewEventHandlers.h>
|
||||||
#include <fabric/scrollview/ScrollViewProps.h>
|
#include <fabric/scrollview/ScrollViewProps.h>
|
||||||
#include <fabric/view/ConcreteViewShadowNode.h>
|
#include <fabric/view/ConcreteViewShadowNode.h>
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ using SharedScrollViewShadowNode = std::shared_ptr<const ScrollViewShadowNode>;
|
||||||
* `ShadowNode` for <ScrollView> component.
|
* `ShadowNode` for <ScrollView> component.
|
||||||
*/
|
*/
|
||||||
class ScrollViewShadowNode final:
|
class ScrollViewShadowNode final:
|
||||||
public ConcreteViewShadowNode<ScrollViewProps> {
|
public ConcreteViewShadowNode<ScrollViewProps, ScrollViewEventHandlers> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue