Skip to content

Instantly share code, notes, and snippets.

@malcommac
Created February 7, 2015 15:10
Show Gist options
  • Save malcommac/4a3fb6d2fbd469dcadc6 to your computer and use it in GitHub Desktop.
Save malcommac/4a3fb6d2fbd469dcadc6 to your computer and use it in GitHub Desktop.
DMScrollViewStack LayoutSubviews
- (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