Created
February 7, 2015 15:10
-
-
Save malcommac/4a3fb6d2fbd469dcadc6 to your computer and use it in GitHub Desktop.
DMScrollViewStack LayoutSubviews
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void) layoutSubviews:(BOOL) aAnimated completion:(void (^)(void)) aCompletion { | |
void (^layoutBlock)(void) = ^void(void) { | |
static BOOL isScrollView; | |
static CGRect visibleRect; | |
static CGFloat currentOffset; | |
static CGRect idealFrame; | |
static CGRect subviewFrame; | |
visibleRect = CGRectMake(0.0f, self.contentOffset.y, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)); | |
currentOffset = 0.0f; | |
NSUInteger idx = 0; | |
for (UIView *subview in viewsArray) { | |
isScrollView = [subview isKindOfClass:[UIScrollView class]]; | |
// This is the ideal (expanded) frame of the subview | |
idealFrame = CGRectMake(0.0f, | |
currentOffset, | |
self.frame.size.width, | |
(isScrollView ? ((UIScrollView*)subview).contentSize.height : [viewsArrayHeight[idx] floatValue])); | |
subviewFrame = idealFrame; | |
if (CGRectIntersectsRect(visibleRect, idealFrame)) { // if subview is visible | |
if (isScrollView) { | |
CGFloat endOfScrollReachedValue = 0; | |
if (CGRectGetMinY(subviewFrame) < self.contentOffset.y) { | |
// When the scrollview offset y is behind the current offset of the outer scroll view we | |
// set the origin of the scrollview at y=0 and the height to the visible height of the scrollview itself from the outer view | |
endOfScrollReachedValue = (self.contentOffset.y+self.frame.size.height - CGRectGetMaxY(idealFrame)); | |
subviewFrame.origin.y = self.contentOffset.y; | |
((UIScrollView*)subview).contentOffset = CGPointMake(0,self.contentOffset.y-idealFrame.origin.y); | |
} else { | |
// We want to mantain the normal content offset until the table offset y > current visible offset | |
((UIScrollView*)subview).contentOffset = CGPointZero; | |
} | |
CGFloat visibleHeight = MIN(self.contentSize.height,MAX(0,self.contentOffset.y+CGRectGetHeight(self.frame)-CGRectGetMinY(subviewFrame))); | |
subviewFrame.size.height = visibleHeight-endOfScrollReachedValue; | |
} | |
// With a simple view frame is the expanded frame (=idealFrame). | |
// With a scroll view we set the size of the scroll big enough to fit only the visible dimension | |
subview.frame = subviewFrame; | |
} else { | |
// If subview is invisible we can set it's frame to zero (with tables and collection view we can avoid loading hidden cells) | |
subviewFrame = CGRectMake(0, subviewFrame.origin.y, 0, 0); | |
} | |
++idx; | |
} | |
self.contentSize = CGSizeMake(CGRectGetWidth(visibleRect),currentOffset); | |
}; | |
if (aAnimated) | |
[UIView animateWithDuration:0.25f animations:layoutBlock completion:^(BOOL finished) { | |
if (aCompletion) aCompletion(); | |
}]; | |
else { | |
layoutBlock(); | |
if (aCompletion) aCompletion(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment