From 5d0e7ccfa8c9ed2e7258b5d8b94cba6141f4ec77 Mon Sep 17 00:00:00 2001 From: featherless Date: Wed, 29 Aug 2018 09:41:03 -0400 Subject: [PATCH] [ButtonBar] Add uppercasesButtonTitles API for modifying title casing behavior. (#4935) This change enables us to expose a similar API in MDCNavigationBar that will enable configuration of title casing behaviors for navigation bar button bars. Step 1/2 for https://github.com/material-components/material-components-ios/issues/2968 --- components/ButtonBar/src/MDCButtonBar.h | 9 +++ components/ButtonBar/src/MDCButtonBar.m | 13 +++ .../src/private/MDCAppBarButtonBarBuilder.m | 1 + .../ButtonBarButtonTitleCasingTests.swift | 81 +++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 components/ButtonBar/tests/unit/ButtonBarButtonTitleCasingTests.swift diff --git a/components/ButtonBar/src/MDCButtonBar.h b/components/ButtonBar/src/MDCButtonBar.h index 6a64cd8a118..56db9676756 100644 --- a/components/ButtonBar/src/MDCButtonBar.h +++ b/components/ButtonBar/src/MDCButtonBar.h @@ -104,6 +104,15 @@ IB_DESIGNABLE */ @property(nonatomic) CGFloat buttonTitleBaseline; +/** + If true, all button titles will be converted to uppercase. + + Changing this property to NO will update the current title string for all buttons. + + Default is YES. + */ +@property(nonatomic) BOOL uppercasesButtonTitles; + /** Sets the title font for the given state for all buttons. diff --git a/components/ButtonBar/src/MDCButtonBar.m b/components/ButtonBar/src/MDCButtonBar.m index 5f54e73dce8..2c1812be5da 100644 --- a/components/ButtonBar/src/MDCButtonBar.m +++ b/components/ButtonBar/src/MDCButtonBar.m @@ -43,6 +43,7 @@ - (void)dealloc { } - (void)commonMDCButtonBarInit { + _uppercasesButtonTitles = YES; _buttonItemsLock = [[NSObject alloc] init]; _layoutPosition = MDCButtonBarLayoutPositionNone; @@ -403,6 +404,18 @@ - (void)setItems:(NSArray *)items { } } +- (void)setUppercasesButtonTitles:(BOOL)uppercasesButtonTitles { + _uppercasesButtonTitles = uppercasesButtonTitles; + + for (NSUInteger i = 0; i < [_buttonViews count]; ++i) { + UIView *viewObj = _buttonViews[i]; + if ([viewObj isKindOfClass:[MDCButton class]]) { + MDCButton *button = (MDCButton *)viewObj; + button.uppercaseTitle = uppercasesButtonTitles; + } + } +} + - (void)setButtonsTitleFont:(UIFont *)font forState:(UIControlState)state { [_defaultBuilder setTitleFont:font forState:state]; diff --git a/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m b/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m index 8a510ae9131..1eb5d21afac 100644 --- a/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m +++ b/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m @@ -129,6 +129,7 @@ - (UIView *)buttonBar:(MDCButtonBar *)buttonBar [MDCAppBarButtonBarBuilder configureButton:button fromButtonItem:buttonItem]; + button.uppercaseTitle = buttonBar.uppercasesButtonTitles; [button setTitleColor:self.buttonTitleColor forState:UIControlStateNormal]; [button setUnderlyingColorHint:self.buttonUnderlyingColor]; for (NSNumber *state in _fonts) { diff --git a/components/ButtonBar/tests/unit/ButtonBarButtonTitleCasingTests.swift b/components/ButtonBar/tests/unit/ButtonBarButtonTitleCasingTests.swift new file mode 100644 index 00000000000..4b1df22f7ad --- /dev/null +++ b/components/ButtonBar/tests/unit/ButtonBarButtonTitleCasingTests.swift @@ -0,0 +1,81 @@ +/* + Copyright 2018-present the Material Components for iOS authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import XCTest +import MaterialComponents.MaterialButtonBar +import MaterialComponents.MaterialButtons + +class ButtonBarButtonTitleCasingTests: XCTestCase { + + var buttonBar: MDCButtonBar! + + override func setUp() { + buttonBar = MDCButtonBar() + } + + func testDefaultCasingIsUppercase() { + // Then + XCTAssertTrue(buttonBar.uppercasesButtonTitles) + } + + func testButtonTitlesAreUppercasedByDefault() { + // Given + let items = [UIBarButtonItem(title: "Text", style: .plain, target: nil, action: nil)] + + // When + buttonBar.items = items + + // Then + XCTAssertTrue(buttonBar.uppercasesButtonTitles) + for view in buttonBar.subviews { + if let button = view as? MDCButton { + XCTAssertEqual(button.title(for: .normal), "TEXT") + } + } + } + + func testButtonTitlesAreNotUppercasedWhenFlagIsDisabledBeforeAssignment() { + // Given + let items = [UIBarButtonItem(title: "Text", style: .plain, target: nil, action: nil)] + + // When + buttonBar.uppercasesButtonTitles = false + buttonBar.items = items + + // Then + for view in buttonBar.subviews { + if let button = view as? MDCButton { + XCTAssertEqual(button.title(for: .normal), "Text") + } + } + } + + func testButtonTitlesAreNotUppercasedWhenFlagIsDisabledAfterAssignment() { + // Given + let items = [UIBarButtonItem(title: "Text", style: .plain, target: nil, action: nil)] + buttonBar.items = items + + // When + buttonBar.uppercasesButtonTitles = false + + // Then + for view in buttonBar.subviews { + if let button = view as? MDCButton { + XCTAssertEqual(button.title(for: .normal), "Text") + } + } + } +}