| Index: ios/chrome/browser/ui/ntp/centering_scrollview.mm
|
| diff --git a/ios/chrome/browser/ui/ntp/centering_scrollview.mm b/ios/chrome/browser/ui/ntp/centering_scrollview.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e6dbf0e2113998237a5e85309ec6c0bbcca78aed
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/ntp/centering_scrollview.mm
|
| @@ -0,0 +1,76 @@
|
| +// Copyright 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import "ios/chrome/browser/ui/ntp/centering_scrollview.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "ios/chrome/browser/ui/ui_util.h"
|
| +
|
| +namespace {
|
| +// Thickness of scrollbar images inserted by UIScrollView (circa iOS 5.0).
|
| +const CGFloat kScrollBarThickness = 7.0;
|
| +} // namespace
|
| +
|
| +@interface CenteringScrollView ()
|
| +// Returns the one and only subview. There may be other subviews
|
| +// (e.g. UIImageView for the scrollbars) created by UIScrollView.
|
| +- (UIView*)findContentView;
|
| +@end
|
| +
|
| +@implementation CenteringScrollView
|
| +
|
| +- (void)layoutSubviews {
|
| + [super layoutSubviews];
|
| +
|
| + // Find the movable content view inside this scroll view.
|
| + UIView* contentView = [self findContentView];
|
| + // UIScrollView does not send |layoutSubviews| message to its subviews.
|
| + // Since layoutSubviews may change the frame of |contentView|, this must be
|
| + // called before the centering computation below.
|
| + [contentView layoutSubviews];
|
| +
|
| + // Place content view in the center of frame.
|
| + CGRect frame = self.frame;
|
| + CGRect contentRect = contentView.frame;
|
| + contentRect.origin = AlignPointToPixel(CGPointMake(
|
| + std::max((frame.size.width - contentRect.size.width) / 2.0, 0.0),
|
| + std::max((frame.size.height - contentRect.size.height) / 2.0, 0.0)));
|
| + contentView.frame = contentRect;
|
| +
|
| + if (contentRect.size.width > frame.size.width ||
|
| + contentRect.size.height > frame.size.height) {
|
| + // If size of content view is larger than frame size, adjust content size
|
| + // so it becomes scrollable.
|
| + self.contentSize =
|
| + CGSizeMake(std::max(contentRect.size.width, frame.size.width),
|
| + std::max(contentRect.size.height, frame.size.height));
|
| + } else {
|
| + // Reset the content size as the view need not be scollable.
|
| + self.contentSize = CGSizeMake(0.0, 0.0);
|
| + }
|
| +}
|
| +
|
| +#pragma mark -
|
| +#pragma mark Private
|
| +
|
| +- (UIView*)findContentView {
|
| + UIView* soloView = nil;
|
| + NSUInteger viewCount = 0;
|
| + for (UIView* view in [self subviews]) {
|
| + // Ignore any UIImageView that has a smaller dimension less than the
|
| + // thickness of a scroll bar. This detection heuristics is based on the
|
| + // scrollbar sizing of iOS UIScrollView circa iOS 5.0. If this changes,
|
| + // the DCHECK following this for-loop will likely fail.
|
| + CGFloat thickness = std::min(view.frame.size.width, view.frame.size.height);
|
| + if ([view isKindOfClass:[UIImageView class]] &&
|
| + thickness <= kScrollBarThickness)
|
| + continue;
|
| + soloView = view;
|
| + ++viewCount;
|
| + }
|
| + DCHECK(viewCount == 1);
|
| + return soloView;
|
| +}
|
| +
|
| +@end
|
|
|