From 64be88398d4c966b24d2f4feeae54db459f75e5f Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Tue, 5 Sep 2017 16:23:56 -0700 Subject: [PATCH] Fix content offset validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Content offset was broken because on initial render contentSize is {0,0} so any positive offset is lost. Also inset top/bottom and left/right were inversed �, this led to bad initial scrolling offset when using contentInset. This fixes it by making sure contentSize is actually measured (not {0,0}. I guess it's possible that the content is ACTUALLY {0,0} but in that case I don't think it really matters). **Test plan** Tested that a scrollview has proper scroll position when specifying contentOffset. Also tested that it works well with contentInset. ```js ``` Closes https://github.com/facebook/react-native/pull/15670 Differential Revision: D5771221 Pulled By: shergin fbshipit-source-id: 455ed8fd5a4ad1ec61780b573d1a8ef1d77dd124 --- React/Views/RCTScrollView.m | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/React/Views/RCTScrollView.m b/React/Views/RCTScrollView.m index 9e8eb88876fe5f..96fea689c77e15 100644 --- a/React/Views/RCTScrollView.m +++ b/React/Views/RCTScrollView.m @@ -315,12 +315,17 @@ - (void)setFrame:(CGRect)frame UIEdgeInsets contentInset = self.contentInset; CGSize contentSize = self.contentSize; - - CGSize boundsSize = self.bounds.size; - - self.contentOffset = CGPointMake( - MAX(-contentInset.top, MIN(contentSize.width - boundsSize.width + contentInset.bottom, originalOffset.x)), - MAX(-contentInset.left, MIN(contentSize.height - boundsSize.height + contentInset.right, originalOffset.y))); + + // If contentSize has not been measured yet we can't check bounds. + if (CGSizeEqualToSize(contentSize, CGSizeZero)) { + self.contentOffset = originalOffset; + } else { + // Make sure offset don't exceed bounds. This could happen on screen rotation. + CGSize boundsSize = self.bounds.size; + self.contentOffset = CGPointMake( + MAX(-contentInset.left, MIN(contentSize.width - boundsSize.width + contentInset.right, originalOffset.x)), + MAX(-contentInset.top, MIN(contentSize.height - boundsSize.height + contentInset.bottom, originalOffset.y))); + } } #if !TARGET_OS_TV