Skip to content
Permalink
Browse files

Add pinWindowTo prop for iOS.

  • Loading branch information...
calebmer committed May 31, 2019
1 parent d9b16e9 commit 8874509405acda979d61504c53cfad4545cae458
@@ -248,6 +248,15 @@ type IOSProps = $ReadOnly<{|
* @platform ios
*/
snapToAlignment?: ?('start' | 'center' | 'end'),
/**
* Pins the currently scrolled window to either the top of its content or
* the bottom. The default behavior is "top". That means when the content in
* the scroll view changes we will keep the offset of the scroll view from
* the top of the content the same. If we set this prop to "bottom" then
* when the content of the scroll view changes we will keep the offset from
* the bottom of the content the same.
*/
pinToButton?: ?('top' | 'bottom'),
/**
* The current scale of the scroll view content. The default value is 1.0.
* @platform ios
@@ -50,6 +50,7 @@
@property (nonatomic, assign) BOOL snapToStart;
@property (nonatomic, assign) BOOL snapToEnd;
@property (nonatomic, copy) NSString *snapToAlignment;
@property (nonatomic, copy) NSString *pinWindowTo;

// NOTE: currently these event props are only declared so we can export the
// event names to JS - we don't call the blocks directly because scroll events
@@ -966,20 +966,29 @@ - (CGPoint)calculateOffsetForContentSize:(CGSize)newContentSize
CGSize oldContentSize = _scrollView.contentSize;
CGSize viewportSize = [self _calculateViewportSize];

BOOL updatedOffsetY = false;
BOOL fitsinViewportY = oldContentSize.height <= viewportSize.height && newContentSize.height <= viewportSize.height;
if (newContentSize.height < oldContentSize.height && !fitsinViewportY) {
CGFloat offsetHeight = oldOffset.y + viewportSize.height;
if (oldOffset.y < 0) {
// overscrolled on top, leave offset alone
updatedOffsetY = true;
} else if (offsetHeight > oldContentSize.height) {
// overscrolled on the bottom, preserve overscroll amount
newOffset.y = MAX(0, oldOffset.y - (oldContentSize.height - newContentSize.height));
updatedOffsetY = true;
} else if (offsetHeight > newContentSize.height) {
// offset falls outside of bounds, scroll back to end of list
newOffset.y = MAX(0, newContentSize.height - viewportSize.height);
updatedOffsetY = true;
}
}

if (!updatedOffsetY && [self.pinWindowTo isEqualToString:@"bottom"]) {
CGFloat oldOffsetBottom = oldContentSize.height - (oldOffset.y + viewportSize.height);
newOffset.y = newContentSize.height - viewportSize.height - oldOffsetBottom;
}

BOOL fitsinViewportX = oldContentSize.width <= viewportSize.width && newContentSize.width <= viewportSize.width;
if (newContentSize.width < oldContentSize.width && !fitsinViewportX) {
CGFloat offsetHeight = oldOffset.x + viewportSize.width;
@@ -86,6 +86,7 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(snapToStart, BOOL)
RCT_EXPORT_VIEW_PROPERTY(snapToEnd, BOOL)
RCT_EXPORT_VIEW_PROPERTY(snapToAlignment, NSString)
RCT_EXPORT_VIEW_PROPERTY(pinWindowTo, NSString)
RCT_REMAP_VIEW_PROPERTY(contentOffset, scrollView.contentOffset, CGPoint)
RCT_EXPORT_VIEW_PROPERTY(onScrollBeginDrag, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock)

0 comments on commit 8874509

Please sign in to comment.
You can’t perform that action at this time.