Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Unified Diff: ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm

Issue 2588733002: Upstream Chrome on iOS source code [9/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm
diff --git a/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm
new file mode 100644
index 0000000000000000000000000000000000000000..dee9ac44434c64255625baba08ca2d6b2e632fa1
--- /dev/null
+++ b/ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.mm
@@ -0,0 +1,94 @@
+// Copyright 2015 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.
+
+#include "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h"
+
+#import <objc/runtime.h>
+
+#import "base/ios/weak_nsobject.h"
+#include "base/mac/scoped_nsobject.h"
+#import "ios/chrome/browser/ui/util/label_observer.h"
+
+namespace {
+// They key under which to associate the line height with the label.
+const void* const kLineHeightKey = &kLineHeightKey;
+// Creates an NSNumber from |line_height| and associates it with |label|.
+void SetAssociatedLineHeight(CGFloat line_height, UILabel* label) {
+ objc_setAssociatedObject(label, kLineHeightKey, @(line_height),
+ OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+// Returns the line height associated with |label|.
+CGFloat GetAssociatedLineHeight(UILabel* label) {
+ return [objc_getAssociatedObject(label, kLineHeightKey) floatValue];
+}
+}
+
+@implementation UILabel (CRUILabelAttributeUtils)
+
+// If there's no text in the label, the line height is whatever is stored in the
+// associated value.
+- (CGFloat)cr_lineHeight {
+ if (!self.text.length || !self.attributedText.string.length)
+ return GetAssociatedLineHeight(self);
+ NSParagraphStyle* style =
+ [self.attributedText attribute:NSParagraphStyleAttributeName
+ atIndex:0
+ effectiveRange:nullptr];
+ return style.maximumLineHeight;
+}
+
+- (void)cr_setLineHeight:(CGFloat)lineHeight {
+ DCHECK_GT(lineHeight, 0.0);
+ // If this is the first time the line height is being set, register the
+ // LabelObserverAction.
+ if (!GetAssociatedLineHeight(self)) {
+ LabelObserver* observer = [LabelObserver observerForLabel:self];
+ [observer addTextChangedAction:^(UILabel* label) {
+ label.cr_lineHeight = GetAssociatedLineHeight(label);
+ }];
+ }
+
+ // Store the new line height as an associated object.
+ SetAssociatedLineHeight(lineHeight, self);
+
+ // If there's no text yet, there's nothing that can be done. The
+ // LabelObserverAction will call this selector again upon changes to the text.
+ if (!self.text.length || !self.attributedText.string.length)
+ return;
+
+ base::scoped_nsobject<NSMutableAttributedString> newString(
+ [self.attributedText mutableCopy]);
+ DCHECK([newString length]);
+ NSParagraphStyle* style = [newString attribute:NSParagraphStyleAttributeName
+ atIndex:0
+ effectiveRange:nullptr];
+ if (!style)
+ style = [NSParagraphStyle defaultParagraphStyle];
+ base::scoped_nsobject<NSMutableParagraphStyle> newStyle([style mutableCopy]);
+ [newStyle setMinimumLineHeight:lineHeight];
+ [newStyle setMaximumLineHeight:lineHeight];
+ [newString addAttribute:NSParagraphStyleAttributeName
+ value:newStyle
+ range:NSMakeRange(0, [newString length])];
+ self.attributedText = newString;
+}
+
+- (void)cr_adjustLineHeightForMaximimumLines:(NSUInteger)maximumLines {
+ CGSize labelSize = self.bounds.size;
+ CGFloat lineHeight = self.cr_lineHeight;
+ CGFloat numberOfLines = floorf(labelSize.height / lineHeight);
+ CGSize maxSize = CGSizeMake(labelSize.width, CGFLOAT_MAX);
+ CGSize textSize = [self sizeThatFits:maxSize];
+
+ // |textSize.height| should be a multiple of |lineHeight|. If this is not the
+ // case, then it is safer to fit one more line to ensure that the text of the
+ // label is not cropped.
+ CGFloat requiredNumberOfLines = ceilf(textSize.height / lineHeight);
+ if (requiredNumberOfLines > numberOfLines) {
+ requiredNumberOfLines = MIN(requiredNumberOfLines, maximumLines);
+ self.cr_lineHeight = floorf(labelSize.height / requiredNumberOfLines);
+ }
+}
+
+@end
« no previous file with comments | « ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h ('k') | ios/chrome/browser/ui/util/CRUILabel+AttributeUtils_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698