File tree Expand file tree Collapse file tree
Libraries/Components/ScrollView Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -248,6 +248,15 @@ type IOSProps = $ReadOnly<{|
248248 * @platform ios
249249 */
250250 snapToAlignment ?: ?( 'start' | 'center' | 'end' ) ,
251+ /**
252+ * Pins the currently scrolled window to either the top of its content or
253+ * the bottom. The default behavior is "top". That means when the content in
254+ * the scroll view changes we will keep the offset of the scroll view from
255+ * the top of the content the same. If we set this prop to "bottom" then
256+ * when the content of the scroll view changes we will keep the offset from
257+ * the bottom of the content the same.
258+ */
259+ pinToButton ?: ?( 'top' | 'bottom' ) ,
251260 /**
252261 * The current scale of the scroll view content. The default value is 1.0.
253262 * @platform ios
Original file line number Diff line number Diff line change 5050@property (nonatomic , assign ) BOOL snapToStart;
5151@property (nonatomic , assign ) BOOL snapToEnd;
5252@property (nonatomic , copy ) NSString *snapToAlignment;
53+ @property (nonatomic , copy ) NSString *pinWindowTo;
5354
5455// NOTE: currently these event props are only declared so we can export the
5556// event names to JS - we don't call the blocks directly because scroll events
Original file line number Diff line number Diff line change @@ -966,20 +966,29 @@ - (CGPoint)calculateOffsetForContentSize:(CGSize)newContentSize
966966 CGSize oldContentSize = _scrollView.contentSize ;
967967 CGSize viewportSize = [self _calculateViewportSize ];
968968
969+ BOOL updatedOffsetY = false ;
969970 BOOL fitsinViewportY = oldContentSize.height <= viewportSize.height && newContentSize.height <= viewportSize.height ;
970971 if (newContentSize.height < oldContentSize.height && !fitsinViewportY) {
971972 CGFloat offsetHeight = oldOffset.y + viewportSize.height ;
972973 if (oldOffset.y < 0 ) {
973974 // overscrolled on top, leave offset alone
975+ updatedOffsetY = true ;
974976 } else if (offsetHeight > oldContentSize.height ) {
975977 // overscrolled on the bottom, preserve overscroll amount
976978 newOffset.y = MAX (0 , oldOffset.y - (oldContentSize.height - newContentSize.height ));
979+ updatedOffsetY = true ;
977980 } else if (offsetHeight > newContentSize.height ) {
978981 // offset falls outside of bounds, scroll back to end of list
979982 newOffset.y = MAX (0 , newContentSize.height - viewportSize.height );
983+ updatedOffsetY = true ;
980984 }
981985 }
982986
987+ if (!updatedOffsetY && [self .pinWindowTo isEqualToString: @" bottom" ]) {
988+ CGFloat oldOffsetBottom = oldContentSize.height - (oldOffset.y + viewportSize.height );
989+ newOffset.y = newContentSize.height - viewportSize.height - oldOffsetBottom;
990+ }
991+
983992 BOOL fitsinViewportX = oldContentSize.width <= viewportSize.width && newContentSize.width <= viewportSize.width ;
984993 if (newContentSize.width < oldContentSize.width && !fitsinViewportX) {
985994 CGFloat offsetHeight = oldOffset.x + viewportSize.width ;
Original file line number Diff line number Diff line change @@ -86,6 +86,7 @@ - (UIView *)view
8686RCT_EXPORT_VIEW_PROPERTY(snapToStart, BOOL )
8787RCT_EXPORT_VIEW_PROPERTY(snapToEnd, BOOL )
8888RCT_EXPORT_VIEW_PROPERTY(snapToAlignment, NSString )
89+ RCT_EXPORT_VIEW_PROPERTY(pinWindowTo, NSString )
8990RCT_REMAP_VIEW_PROPERTY(contentOffset, scrollView.contentOffset, CGPoint)
9091RCT_EXPORT_VIEW_PROPERTY(onScrollBeginDrag, RCTDirectEventBlock)
9192RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock)
You can’t perform that action at this time.
0 commit comments