OLD | NEW |
(Empty) | |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/ui/ntp/centering_scrollview.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "ios/chrome/browser/ui/ui_util.h" |
| 9 |
| 10 namespace { |
| 11 // Thickness of scrollbar images inserted by UIScrollView (circa iOS 5.0). |
| 12 const CGFloat kScrollBarThickness = 7.0; |
| 13 } // namespace |
| 14 |
| 15 @interface CenteringScrollView () |
| 16 // Returns the one and only subview. There may be other subviews |
| 17 // (e.g. UIImageView for the scrollbars) created by UIScrollView. |
| 18 - (UIView*)findContentView; |
| 19 @end |
| 20 |
| 21 @implementation CenteringScrollView |
| 22 |
| 23 - (void)layoutSubviews { |
| 24 [super layoutSubviews]; |
| 25 |
| 26 // Find the movable content view inside this scroll view. |
| 27 UIView* contentView = [self findContentView]; |
| 28 // UIScrollView does not send |layoutSubviews| message to its subviews. |
| 29 // Since layoutSubviews may change the frame of |contentView|, this must be |
| 30 // called before the centering computation below. |
| 31 [contentView layoutSubviews]; |
| 32 |
| 33 // Place content view in the center of frame. |
| 34 CGRect frame = self.frame; |
| 35 CGRect contentRect = contentView.frame; |
| 36 contentRect.origin = AlignPointToPixel(CGPointMake( |
| 37 std::max((frame.size.width - contentRect.size.width) / 2.0, 0.0), |
| 38 std::max((frame.size.height - contentRect.size.height) / 2.0, 0.0))); |
| 39 contentView.frame = contentRect; |
| 40 |
| 41 if (contentRect.size.width > frame.size.width || |
| 42 contentRect.size.height > frame.size.height) { |
| 43 // If size of content view is larger than frame size, adjust content size |
| 44 // so it becomes scrollable. |
| 45 self.contentSize = |
| 46 CGSizeMake(std::max(contentRect.size.width, frame.size.width), |
| 47 std::max(contentRect.size.height, frame.size.height)); |
| 48 } else { |
| 49 // Reset the content size as the view need not be scollable. |
| 50 self.contentSize = CGSizeMake(0.0, 0.0); |
| 51 } |
| 52 } |
| 53 |
| 54 #pragma mark - |
| 55 #pragma mark Private |
| 56 |
| 57 - (UIView*)findContentView { |
| 58 UIView* soloView = nil; |
| 59 NSUInteger viewCount = 0; |
| 60 for (UIView* view in [self subviews]) { |
| 61 // Ignore any UIImageView that has a smaller dimension less than the |
| 62 // thickness of a scroll bar. This detection heuristics is based on the |
| 63 // scrollbar sizing of iOS UIScrollView circa iOS 5.0. If this changes, |
| 64 // the DCHECK following this for-loop will likely fail. |
| 65 CGFloat thickness = std::min(view.frame.size.width, view.frame.size.height); |
| 66 if ([view isKindOfClass:[UIImageView class]] && |
| 67 thickness <= kScrollBarThickness) |
| 68 continue; |
| 69 soloView = view; |
| 70 ++viewCount; |
| 71 } |
| 72 DCHECK(viewCount == 1); |
| 73 return soloView; |
| 74 } |
| 75 |
| 76 @end |
OLD | NEW |