From b9b315dd7ad0587dc1cea4f92672910eb47af199 Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 6 Apr 2016 15:08:08 -0400 Subject: [PATCH 01/92] [install scripts] fixed install brew and pip scripts actually install pip and brew Reviewers: featherless, #mdc_ios_owners Reviewed By: featherless, #mdc_ios_owners Projects: #material_components_ios Differential Revision: http://codereview.cc/D496 --- scripts/install_brew | 2 +- scripts/install_pip | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install_brew b/scripts/install_brew index 72a0f336c0c..1e9a81281d9 100755 --- a/scripts/install_brew +++ b/scripts/install_brew @@ -18,6 +18,6 @@ # # This is not required for anyone but core team members. -if [ ! brew -v >/dev/null 2>&1 ]; then +if [ ! $(brew -v >/dev/null 2>&1) ]; then /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" fi diff --git a/scripts/install_pip b/scripts/install_pip index fbc3670ce24..11180031cff 100755 --- a/scripts/install_pip +++ b/scripts/install_pip @@ -18,6 +18,6 @@ # # This is not required for anyone but core team members. -if [ ! pip --version >/dev/null 2>&1 ]; then +if [ ! $(pip --version >/dev/null 2>&1) ]; then sudo easy_install pip fi From 237ca2644374759a71cbfeb75e21ad23c1ff089a Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Sat, 26 Mar 2016 01:23:08 -0400 Subject: [PATCH 02/92] Add api_diff script for generating api diffs. Summary: This tool can be used to generate API diffs for releases. Example output from `scripts/api_diff.sh -o v2.1.0 -n develop`: ``` ---------------- FlexibleHeader ----------------------- MDCFlexibleHeaderViewController.h --------------------------------- MDCFlexibleHeaderViewController Protocols From: UIScrollViewDelegate To: UIScrollViewDelegate, UITableViewDelegate ---------------- FontDiskLoader ----------------------- New component ---------------- RobotoFontLoader ----------------------- New component ---------------- Typography ----------------------- MDCFontResource.h ----------------- - MDCFontResource - -[MDCFontResource initWithName:URL:] - -[MDCFontResource initWithFontName:filename:bundleFileName:baseBundle:] - MDCFontResource.fontName - MDCFontResource.fontURL - -[MDCFontResource registerFont] - MDCFontResource.isRegistered - MDCFontResource.hasFailedRegistration - -[MDCFontResource fontOfSize:] MDCRobotoFontLoader.h --------------------- - MDCRobotoFontLoader - +[MDCRobotoFontLoader sharedInstance] - -[MDCRobotoFontLoader lightFontOfSize:] - -[MDCRobotoFontLoader regularFontOfSize:] - -[MDCRobotoFontLoader mediumFontOfSize:] - -[MDCRobotoFontLoader boldFontOfSize:] - -[MDCRobotoFontLoader lightItalicFontOfSize:] - -[MDCRobotoFontLoader italicFontOfSize:] - -[MDCRobotoFontLoader mediumItalicFontOfSize:] - -[MDCRobotoFontLoader boldItalicFontOfSize:] MDCTypography.h --------------- - -[MDCTypographyFontLoader lightFontOfSize:] - -[MDCTypographyFontLoader regularFontOfSize:] - -[MDCTypographyFontLoader mediumFontOfSize:] + MDCTypographyFontLoading + -[MDCTypographyFontLoading lightFontOfSize:] + -[MDCTypographyFontLoading regularFontOfSize:] + -[MDCTypographyFontLoading mediumFontOfSize:] +[MDCTypography setFontLoader:] Declaration From: + (void)setFontLoader:(nonnull id)fontLoader To: + (void)setFontLoader:(nonnull id)fontLoader MDCSystemFontLoader Protocols From: MDCTypographyFontLoader To: MDCTypographyFontLoading MDCTypographyFontLoader Protocols From: NSObject To: MDCTypographyFontLoading Availability From: Available To: Deprecated Deprecation Message From: (none) To: Use MDCTypographyFontLoading instead ``` Reviewers: #mdc_ios_owners, ajsecord Reviewed By: #mdc_ios_owners, ajsecord Projects: #material_components_ios Differential Revision: http://codereview.cc/D372 --- .gitignore | 1 + scripts/api_diff | 151 ++++++++++++++++++++++++++++++++++++ scripts/objc_diff_xml_to_md | 115 +++++++++++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100755 scripts/api_diff create mode 100755 scripts/objc_diff_xml_to_md diff --git a/.gitignore b/.gitignore index 5fdb994986f..0ad1f8e375f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build_tests/CocoapodsObjCApp/CocoapodsObjCApp.xcworkspace build_tests/CocoapodsSwiftApp/CocoapodsSwiftApp.xcworkspace scripts/external/material-design-icons/ +scripts/external/objc-diff/ # Xcode # diff --git a/scripts/api_diff b/scripts/api_diff new file mode 100755 index 00000000000..da588f55445 --- /dev/null +++ b/scripts/api_diff @@ -0,0 +1,151 @@ +#!/bin/bash +# +# Copyright 2016-present Google Inc. 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. + +old_commit="" +new_commit="" +verbose=0 + +usage() { + echo "Usage: $0 -o [old commit] -n [new commit]]" + echo + echo "Example usage: $0 -o v2.0.0 -n develop" +} + +while getopts "h?vo:n:" opt; do + case "$opt" in + h|\?) + usage + exit 0 + ;; + v) verbose=1 + ;; + o) old_commit=$(git rev-parse $OPTARG) + ;; + n) new_commit=$(git rev-parse $OPTARG) + ;; + esac +done + +if [[ -z "$old_commit" || -z "$new_commit" ]]; then + usage + exit 0 +fi + +validate_commit() { + git cat-file -t $1 >> /dev/null 2> /dev/null || { echo "$1 is not a valid commit."; exit 1; } +} + +validate_commit $old_commit +validate_commit $new_commit + +# Compute directories relative to the script's known location in scripts/ +SCRIPTS_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +REPO_ROOT_PATH="$( cd "$( dirname $SCRIPTS_PATH )" && pwd )" + +# Where to fetch the objc-diff repo from +OBJC_DIFF_REPO_URL="https://github.com/mattstevens/objc-diff.git" + +# Where to install the objc-diff repo +OBJC_DIFF_REPO_PATH="$SCRIPTS_PATH/external/objc-diff" +OBJC_DIFF_BINARY_RELATIVE_PATH="build/Release/objc-diff" +OBJC_DIFF_BINARY_PATH=$OBJC_DIFF_REPO_PATH/$OBJC_DIFF_BINARY_RELATIVE_PATH + +SYSROOT="$(xcode-select --print-path)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" + +echo "Fetching objc-diff..." + +# Runs git commands in the objc-diff repository directory. +git_objc_diff() { + pushd $OBJC_DIFF_REPO_PATH >> /dev/null + git "$@" + popd >> /dev/null +} + +# Clone/update the objc-diff repo +if [ ! -d "$OBJC_DIFF_REPO_PATH" ]; then + git clone "$OBJC_DIFF_REPO_URL" "$OBJC_DIFF_REPO_PATH" || { echo "Failed to clone."; exit 1; } +else + git_objc_diff fetch || { echo "Failed to update objc-diff."; exit 1; } +fi + +# Build objc-diff binary +xcodebuild build -project $OBJC_DIFF_REPO_PATH/OCDiff.xcodeproj -target OCDiff -configuration Release + +# Verify objc-diff binary existence +if [ ! -f "$OBJC_DIFF_BINARY_PATH" ]; then + echo "Unable to find objc-diff at $OBJC_DIFF_BINARY_PATH" + exit 1 +fi + +objc_diff() { + "$OBJC_DIFF_BINARY_PATH" "$@" +} + +TMP_PATH=$(mktemp -d) + +OLD_ROOT_PATH="$TMP_PATH/old" +NEW_ROOT_PATH="$TMP_PATH/new" + +# prep_repo +prep_repo() { + if [ ! -d "$1" ]; then + git clone "$REPO_ROOT_PATH" "$1" || { echo "Failed to clone."; exit 1; } + fi + pushd $1 >> /dev/null + git remote add github git@github.com:google/material-components-ios.git + git fetch || { echo "Failed to update repo."; exit 1; } + git checkout "$2" --quiet + popd >> /dev/null +} + +prep_repo $OLD_ROOT_PATH $old_commit +prep_repo $NEW_ROOT_PATH $new_commit + +old_header_search_paths="" +new_header_search_paths="" +for d in $NEW_ROOT_PATH/components/*/src; do + folder=$(dirname $d) + component=$(basename $folder) + old_header_search_paths="$old_header_search_paths --oldargs -I$OLD_ROOT_PATH/components/$component/src/ " + new_header_search_paths="$new_header_search_paths --newargs -I$NEW_ROOT_PATH/components/$component/src/ " +done + +for d in $NEW_ROOT_PATH/components/*/src; do + folder=$(dirname $d) + component=$(basename $folder) + + echo + echo "### $component" + echo + + if [ ! -d "$OLD_ROOT_PATH/components/$component/src" ]; then + echo "**New component.**" + continue + fi + + objc_diff \ + --xml \ + --sdk iphonesimulator \ + --old "$OLD_ROOT_PATH/components/$component/src" \ + --new "$NEW_ROOT_PATH/components/$component/src" \ + $old_header_search_paths \ + $new_header_search_paths | $SCRIPTS_PATH/objc_diff_xml_to_md $old_commit $new_commit components/$component/src +done + +if [ ! -z "$TMP_PATH" ]; then + echo "Cleaning up..." + rm -rf $TMP_PATH +fi diff --git a/scripts/objc_diff_xml_to_md b/scripts/objc_diff_xml_to_md new file mode 100755 index 00000000000..8bfc3befc9b --- /dev/null +++ b/scripts/objc_diff_xml_to_md @@ -0,0 +1,115 @@ +#!/usr/bin/php + '[deleted]', + 'addition' => '[new]', + 'modification' => '[modified]' +); + +$typeToPastTenseVerb = array( + 'removal' => 'removed', + 'addition' => 'added', + 'modification' => 'modified' +); + +$typeToCommit = array( + 'removal' => $argv[1], + 'addition' => $argv[2], + 'modification' => $argv[1] +); + +$output = array(); + +function getModificationWithType($modifications, $type) { + foreach ($modifications as $modification) { + if ($modification->type == $type) { + return $modification; + } + } + return false; +} + +if (!empty($structure)) { + foreach ($structure->difference as $delta) { + if (startsWith($delta->path, '..') || startsWith(strtolower($delta->path), 'private')) { + // Ignore source not in this component and source that is private + continue; + } + + $type = $typeToSymbol[strval($delta->type)]; + $verb = $typeToPastTenseVerb[strval($delta->type)]; + $commit = $typeToCommit[strval($delta->type)]; + $url = BASE_URL."/blob/$commit/".$argv[3].'/'.$delta->path.'#L'.$delta->lineNumber; + + $link = "[`".$delta->name."`]($url)"; + + $lines = array(); + + if ($delta->type == 'modification') { + $modifications = $delta->modifications->modification; + $types = array(); + foreach ($modifications as $modification) { + $types []= $modification->type; + } + + $didOutputLines = false; + + if (count(array_diff($types, array('availability', 'deprecationMessage'))) == 0) { + $availability = getModificationWithType($modifications, 'availability'); + $message = getModificationWithType($modifications, 'deprecationMessage'); + if ($availability->currentValue == 'Deprecated') { + $lines []= "- [deprecated] $link."; + $lines []= "*$message->currentValue*"; + $didOutputLines = true; + } + } + + if (!$didOutputLines) { + $lines []= "- $type $link"; + $lines []= ""; + $lines []= "| From | To | Kind |"; + $lines []= "|:---- |:-- |:---- |"; + + foreach ($modifications as $modification) { + $lines []= "| ". $modification->previousValue ." | ". $modification->currentValue ." | ".$modification->type ." |"; + } + $lines []= ""; + } + + } else { + $lines = array("- $type $link"); + } + + $output []= $lines; + } +} + +if (empty($output)) { + echo "No public API changes detected.\n"; + exit(0); +} + +$firstlines = array(); +foreach ($output as $lines) { + $firstlines []= $lines[0]; +} + +array_multisort($output, $firstlines); + +foreach ($output as $lines) { + echo implode("\n", $lines)."\n"; +} + +?> \ No newline at end of file From 1108fa51e248d29e66ea95a8138f451663192c36 Mon Sep 17 00:00:00 2001 From: Jason Striegel Date: Wed, 6 Apr 2016 16:18:59 -0400 Subject: [PATCH 03/92] HP copy update. --- site-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site-index.md b/site-index.md index b2165671767..79c5be336c5 100644 --- a/site-index.md +++ b/site-index.md @@ -9,7 +9,7 @@ layout: "homepage" # Material Components for iOS -An easy way to create apps with Material Design. +An easy way to create beautiful apps with modular and customizable UI components. [Get Started](#quickstart) From 93eefa8efd6eded50c825e50f5f593e0ecd61185 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Wed, 6 Apr 2016 16:23:44 -0400 Subject: [PATCH 04/92] api_diff now respects the verbose flag. Reviewers: #mdc_ios_owners, ajsecord Reviewed By: #mdc_ios_owners, ajsecord Subscribers: ajsecord Projects: #material_components_ios Differential Revision: http://codereview.cc/D498 --- scripts/api_diff | 51 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/scripts/api_diff b/scripts/api_diff index da588f55445..0221003bef9 100755 --- a/scripts/api_diff +++ b/scripts/api_diff @@ -16,7 +16,7 @@ old_commit="" new_commit="" -verbose=0 +VERBOSE=0 usage() { echo "Usage: $0 -o [old commit] -n [new commit]]" @@ -30,7 +30,7 @@ while getopts "h?vo:n:" opt; do usage exit 0 ;; - v) verbose=1 + v) VERBOSE=1 ;; o) old_commit=$(git rev-parse $OPTARG) ;; @@ -39,11 +39,23 @@ while getopts "h?vo:n:" opt; do esac done +log() { + if [ "$VERBOSE" -eq "1" ]; then + echo "$@" + fi +} + if [[ -z "$old_commit" || -z "$new_commit" ]]; then usage exit 0 fi +logger() { + while read data; do + log "$data" + done +} + validate_commit() { git cat-file -t $1 >> /dev/null 2> /dev/null || { echo "$1 is not a valid commit."; exit 1; } } @@ -65,24 +77,30 @@ OBJC_DIFF_BINARY_PATH=$OBJC_DIFF_REPO_PATH/$OBJC_DIFF_BINARY_RELATIVE_PATH SYSROOT="$(xcode-select --print-path)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" -echo "Fetching objc-diff..." +log "Fetching objc-diff..." # Runs git commands in the objc-diff repository directory. git_objc_diff() { pushd $OBJC_DIFF_REPO_PATH >> /dev/null - git "$@" + git "$@" 2>&1 | logger popd >> /dev/null } # Clone/update the objc-diff repo if [ ! -d "$OBJC_DIFF_REPO_PATH" ]; then - git clone "$OBJC_DIFF_REPO_URL" "$OBJC_DIFF_REPO_PATH" || { echo "Failed to clone."; exit 1; } + git clone "$OBJC_DIFF_REPO_URL" "$OBJC_DIFF_REPO_PATH" \ + 2>&1 | logger || { echo "Failed to clone."; exit 1; } else - git_objc_diff fetch || { echo "Failed to update objc-diff."; exit 1; } + git_objc_diff fetch \ + 2>&1 | logger || { echo "Failed to update objc-diff."; exit 1; } fi # Build objc-diff binary -xcodebuild build -project $OBJC_DIFF_REPO_PATH/OCDiff.xcodeproj -target OCDiff -configuration Release +xcodebuild build \ + -project $OBJC_DIFF_REPO_PATH/OCDiff.xcodeproj \ + -target OCDiff \ + -configuration Release \ + 2>&1 | logger # Verify objc-diff binary existence if [ ! -f "$OBJC_DIFF_BINARY_PATH" ]; then @@ -102,12 +120,14 @@ NEW_ROOT_PATH="$TMP_PATH/new" # prep_repo prep_repo() { if [ ! -d "$1" ]; then - git clone "$REPO_ROOT_PATH" "$1" || { echo "Failed to clone."; exit 1; } + git clone "$REPO_ROOT_PATH" "$1" \ + 2>&1 | logger || { echo "Failed to clone."; exit 1; } fi pushd $1 >> /dev/null - git remote add github git@github.com:google/material-components-ios.git - git fetch || { echo "Failed to update repo."; exit 1; } - git checkout "$2" --quiet + git remote add github git@github.com:google/material-components-ios.git 2>&1 | logger + git fetch \ + 2>&1 | logger || { echo "Failed to update repo."; exit 1; } + git checkout "$2" 2>&1 | logger popd >> /dev/null } @@ -123,6 +143,13 @@ for d in $NEW_ROOT_PATH/components/*/src; do new_header_search_paths="$new_header_search_paths --newargs -I$NEW_ROOT_PATH/components/$component/src/ " done +echo "## API diffs" +echo +echo "Auto-generated by running:" +echo +echo " scripts/api_diff -o origin/master -n latest-release" + + for d in $NEW_ROOT_PATH/components/*/src; do folder=$(dirname $d) component=$(basename $folder) @@ -146,6 +173,6 @@ for d in $NEW_ROOT_PATH/components/*/src; do done if [ ! -z "$TMP_PATH" ]; then - echo "Cleaning up..." + log "Cleaning up..." rm -rf $TMP_PATH fi From 489d4355ae5cfb241c261685b397e9ca88260d41 Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 6 Apr 2016 15:27:38 -0400 Subject: [PATCH 05/92] [Roboto] Added simple example Reviewers: #mdc_ios_owners, featherless Reviewed By: #mdc_ios_owners, featherless Subscribers: featherless Projects: #material_components_ios Differential Revision: http://codereview.cc/D497 --- ...otoFontLoaderSimpleExampleViewController.h | 20 +++++++++ ...otoFontLoaderSimpleExampleViewController.m | 42 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.h create mode 100644 components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.m diff --git a/components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.h b/components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.h new file mode 100644 index 00000000000..1555720fcc1 --- /dev/null +++ b/components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.h @@ -0,0 +1,20 @@ +/* + Copyright 2015-present Google Inc. 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 + +@interface RobotoFontLoaderSimpleExampleViewController : UIViewController +@end diff --git a/components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.m b/components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.m new file mode 100644 index 00000000000..f2c74685f61 --- /dev/null +++ b/components/RobotoFontLoader/examples/RobotoFontLoaderSimpleExampleViewController.m @@ -0,0 +1,42 @@ +/* + Copyright 2015-present Google Inc. 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 "RobotoFontLoaderSimpleExampleViewController.h" +#import "MaterialRobotoFontLoader.h" + +@implementation RobotoFontLoaderSimpleExampleViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. + self.view.backgroundColor = [UIColor whiteColor]; + + // Consider using the named styles provided by the Typography component instead of specific font + // sizes. See https://github.com/google/material-components-ios/tree/develop/components/Typography + UILabel *label = [[UILabel alloc] init]; + label.text = @"This is Roboto regular 16"; + label.font = [[MDCRobotoFontLoader sharedInstance] regularFontOfSize:16]; + + [label sizeToFit]; + label.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds)); + [self.view addSubview:label]; +} + ++ (NSArray *)catalogBreadcrumbs { + return @[ @"RobotoFontLoader", @"Readme demo" ]; +} + +@end From fdaba18e1bca7688423f619178daf074a8c31edb Mon Sep 17 00:00:00 2001 From: Adrian Secord Date: Thu, 7 Apr 2016 09:50:08 -0400 Subject: [PATCH 06/92] Removed deprecated Ink APIs. Reviewers: #mdc_ios_owners, junius Reviewed By: #mdc_ios_owners, junius Subscribers: junius Projects: #material_components_ios Differential Revision: http://codereview.cc/D505 --- components/Ink/src/MDCInkView.h | 14 ----------- components/Ink/src/MDCInkView.m | 42 --------------------------------- 2 files changed, 56 deletions(-) diff --git a/components/Ink/src/MDCInkView.h b/components/Ink/src/MDCInkView.h index ed9e5c572b7..32b00127721 100644 --- a/components/Ink/src/MDCInkView.h +++ b/components/Ink/src/MDCInkView.h @@ -108,18 +108,4 @@ typedef NS_ENUM(NSInteger, MDCInkStyle) { */ - (void)cancelAllAnimationsAnimated:(BOOL)animated; -#pragma mark - Deprecated - -@property(nonatomic, assign) BOOL fillsBackgroundOnSpread - __deprecated_msg("Use MDCInkViewStyle instead."); -@property(nonatomic, assign) BOOL clipsRippleToBounds - __deprecated_msg("Use MDCInkViewStyle instead."); -@property(nonatomic, assign) BOOL gravitatesInk __deprecated_msg("No replacement available."); -- (void)reset __deprecated_msg("Use cancelAllAnimationsAnimated: intead."); -- (void)spreadFromPoint:(CGPoint)point completion:(nullable MDCInkCompletionBlock)completionBlock - __deprecated_msg("Use startTouchBeganAnimationAtPoint:completion: instead."); -- (void)evaporateWithCompletion:(nullable MDCInkCompletionBlock)completionBlock - __deprecated_msg("Use startTouchEndedAnimationAtPoint:completion: instead."); -- (void)evaporateToPoint:(CGPoint)point completion:(nullable MDCInkCompletionBlock)completionBlock - __deprecated_msg("Use startTouchEndedAnimationAtPoint:completion: instead."); @end diff --git a/components/Ink/src/MDCInkView.m b/components/Ink/src/MDCInkView.m index 8a9e0d30e99..e25cce5f3fd 100644 --- a/components/Ink/src/MDCInkView.m +++ b/components/Ink/src/MDCInkView.m @@ -119,46 +119,4 @@ - (UIColor *)defaultInkColor { return [[UIColor alloc] initWithWhite:0 alpha:0.06f]; } -#pragma mark - Deprecated - -- (BOOL)fillsBackgroundOnSpread { - return self.inkStyle == MDCInkStyleBounded ? YES : NO; -} - -- (void)setFillsBackgroundOnSpread:(BOOL)fillsBackgroundOnSpread { - self.inkStyle = fillsBackgroundOnSpread ? MDCInkStyleBounded : MDCInkStyleUnbounded; -} - -- (BOOL)clipsRippleToBounds { - return self.inkStyle == MDCInkStyleBounded ? YES : NO; -} - -- (void)setClipsRippleToBounds:(BOOL)clipsRippleToBounds { - self.inkStyle = clipsRippleToBounds ? MDCInkStyleBounded : MDCInkStyleUnbounded; -} - -- (BOOL)gravitatesInk { - return NO; -} - -- (void)setGravitatesInk:(BOOL)gravitatesInk { -} - -- (void)reset { - [self cancelAllAnimationsAnimated:YES]; -} - -- (void)spreadFromPoint:(CGPoint)point completion:(nullable MDCInkCompletionBlock)completionBlock { - [self startTouchBeganAnimationAtPoint:point completion:completionBlock]; -} - -- (void)evaporateWithCompletion:(nullable MDCInkCompletionBlock)completionBlock { - // Note the point is currently ignored. - [self startTouchEndedAnimationAtPoint:CGPointZero completion:completionBlock]; -} - -- (void)evaporateToPoint:(CGPoint)point completion:(nullable MDCInkCompletionBlock)completionBlock { - [self startTouchEndedAnimationAtPoint:point completion:completionBlock]; -} - @end From 6f79195001fe2afca913658a581d428a7c34f2f0 Mon Sep 17 00:00:00 2001 From: Adrian Secord Date: Thu, 7 Apr 2016 10:08:06 -0400 Subject: [PATCH 07/92] [Buttons] Changes from API review. Summary: Syncing API review comments to background colors. Merge branch 'develop' into button-api-changes shouldCapitalizeTitle to uppercaseTitle. underlyingColor to underlyingColorHint. elevationForState: comments. Final changes. Reviewers: #mdc_ios_owners, featherless Reviewed By: #mdc_ios_owners, featherless Projects: #material_components_ios Differential Revision: http://codereview.cc/D504 --- components/Buttons/src/MDCButton.h | 74 ++++++++++-------- components/Buttons/src/MDCButton.m | 80 +++++++++++++------- components/Buttons/src/MDCFlatButton.h | 8 +- components/Buttons/src/MDCFloatingButton.h | 18 ++++- components/Buttons/src/MDCFloatingButton.m | 8 +- components/Buttons/tests/unit/ButtonsTests.m | 8 +- 6 files changed, 122 insertions(+), 74 deletions(-) diff --git a/components/Buttons/src/MDCButton.h b/components/Buttons/src/MDCButton.h index 3079983429e..d9ddb9c41bc 100644 --- a/components/Buttons/src/MDCButton.h +++ b/components/Buttons/src/MDCButton.h @@ -34,8 +34,7 @@ @interface MDCButton : UIButton /** - A color used as the button's @c backgroundColor. - The default value is nil, which results in a transparent background color. + A color used as the button's @c backgroundColor for @c state. @param state The state. @return The background color. @@ -45,15 +44,13 @@ /** A color used as the button's @c backgroundColor. + If left unset or reset to nil for a given state, then a default blue color is used. + @param backgroundColor The background color. @param state The state. */ - (void)setBackgroundColor:(nullable UIColor *)backgroundColor forState:(UIControlState)state; -/** Use @c setBackgroundColor:forState: instead. */ -- (void)setBackgroundColor:(nullable UIColor *)backgroundColor - __deprecated_msg("Use setBackgroundColor:forState: instead."); - /** The ink color of the button. */ @property(nonatomic, strong, null_resettable) UIColor *inkColor; @@ -69,26 +66,21 @@ /** The alpha value that will be applied when the button is disabled. Most clients can leave this as - the default value to get a semitransparent button automatically. + the default value to get a semi-transparent button automatically. */ @property(nonatomic) CGFloat disabledAlpha; -/** - Should the button raise when touched? - - Default is YES. Prefer using the factory methods to configure this based on the button type. - */ -@property(nonatomic) BOOL shouldRaiseOnTouch; - /** If true, converts the button title to uppercase. Changing this property to NO will not update the current title string. Default is YES and is recommended whenever possible. */ -@property(nonatomic) BOOL shouldCapitalizeTitle; +@property(nonatomic, getter=isUppercaseTitle) BOOL uppercaseTitle; /** + Insets to apply to the button’s hit area. + Allows the button to detect touches outside of its bounds. A negative value indicates an extension past the bounds. @@ -97,23 +89,20 @@ @property(nonatomic) UIEdgeInsets hitAreaInsets; /** - The color of the view behind the button, used to calculate accessible text colors. + The apparent background color as seen by the user, i.e. the color of the view behind the button. + + The underlying color hint is used by buttons to calculate accessible title text colors when in + states with transparent background colors. The hint is used whenever the button changes state such + that the background color changes, for example, setting the background color or disabling the + button. - For flat buttons with the default transparent background, this is the color of the surrounding - area (and thus the button's background). For all other buttons, this is the color of view - underneath the button. + For flat buttons, this is the color of both the surrounding area and the button's background. + For raised and floating buttons, this is the color of view underneath the button. The default is nil. If left unset, buttons will likely have an incorrect appearance when - disabled. Additionally, flat buttons will have incorrect text colors. + disabled. Additionally, flat buttons might have text colors with low accessibility. */ -@property(nonatomic, strong, nullable) UIColor *underlyingColor; - -/** - From UIButton's documentation: "If you subclass UIButton, this method does not return an instance - of your subclass. If you want to create an instance of a specific subclass, you must alloc/init - the button directly." - */ -+ (nonnull instancetype)buttonWithType:(UIButtonType)buttonType NS_UNAVAILABLE; +@property(nonatomic, strong, nullable) UIColor *underlyingColorHint; /** Sets the enabled state with optional animation. */ - (void)setEnabled:(BOOL)enabled animated:(BOOL)animated; @@ -121,11 +110,8 @@ /** Returns the elevation for a particular control state. - The default values are particular to each subclass of MDCButton. - The default value for UIControlStateNormal is 0. The default value for UIControlStateSelected is - twice greater than the value of UIControlStateNormal (which might have been set to value other - than zero by the caller). The default values for all other states is the value of - UIControlStateNormal. + The default values depend on the kind of button, for example, flat buttons in the + UIControlStateNormal state have zero elevation. @param state The control state to retrieve the elevation. @return The elevation for the requested state. @@ -149,4 +135,26 @@ */ - (void)resetElevationForState:(UIControlState)state; +#pragma mark - UIButton changes + +/** + From UIButton's documentation: "If you subclass UIButton, this method does not return an instance + of your subclass. If you want to create an instance of a specific subclass, you must alloc/init + the button directly." + */ ++ (nonnull instancetype)buttonWithType:(UIButtonType)buttonType NS_UNAVAILABLE; + +#pragma mark - Deprecated + +- (void)setBackgroundColor:(nullable UIColor *)backgroundColor + __deprecated_msg("Use setBackgroundColor:forState: instead."); + +@property(nonatomic) BOOL shouldRaiseOnTouch + __deprecated_msg("Use MDCFlatButton instead of shouldRaiseOnTouch = NO"); + +@property(nonatomic) BOOL shouldCapitalizeTitle __deprecated_msg("Use uppercaseTitle instead."); + +@property(nonatomic, strong, nullable) UIColor *underlyingColor + __deprecated_msg("Use underlyingColorHint instead."); + @end diff --git a/components/Buttons/src/MDCButton.m b/components/Buttons/src/MDCButton.m index 0ecc0af8971..2ae3597a09d 100644 --- a/components/Buttons/src/MDCButton.m +++ b/components/Buttons/src/MDCButton.m @@ -36,8 +36,10 @@ @"MDCButtonDisabledBackgroundColorDarkKey"; static NSString *const MDCButtonInkViewInkColorKey = @"MDCButtonInkViewInkColorKey"; static NSString *const MDCButtonShouldRaiseOnTouchKey = @"MDCButtonShouldRaiseOnTouchKey"; -static NSString *const MDCButtonShouldCapitalizeTitleKey = @"MDCButtonShouldCapitalizeTitleKey"; -static NSString *const MDCButtonUnderlyingColorKey = @"MDCButtonUnderlyingColorKey"; +// Previous value kept for backwards compatibility. +static NSString *const MDCButtonUppercaseTitleKey = @"MDCButtonShouldCapitalizeTitleKey"; +// Previous value kept for backwards compatibility. +static NSString *const MDCButtonUnderlyingColorHintKey = @"MDCButtonUnderlyingColorKey"; static NSString *const MDCButtonUserElevationsKey = @"MDCButtonUserElevationsKey"; static const NSTimeInterval MDCButtonAnimationDuration = 0.2; @@ -61,7 +63,7 @@ static inline BOOL MDCButtonFloatIsExactlyZero(CGFloat value) { alpha:1]; } -static NSAttributedString *capitalizeAttributedString(NSAttributedString *string) { +static NSAttributedString *uppercaseAttributedString(NSAttributedString *string) { // Store the attributes. NSMutableArray *attributes = [NSMutableArray array]; [string enumerateAttributesInRange:NSMakeRange(0, [string length]) @@ -141,12 +143,12 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { self.shouldRaiseOnTouch = [aDecoder decodeBoolForKey:MDCButtonShouldRaiseOnTouchKey]; } - if ([aDecoder containsValueForKey:MDCButtonShouldCapitalizeTitleKey]) { - self.shouldCapitalizeTitle = [aDecoder decodeBoolForKey:MDCButtonShouldCapitalizeTitleKey]; + if ([aDecoder containsValueForKey:MDCButtonUppercaseTitleKey]) { + self.uppercaseTitle = [aDecoder decodeBoolForKey:MDCButtonUppercaseTitleKey]; } - if ([aDecoder containsValueForKey:MDCButtonUnderlyingColorKey]) { - self.underlyingColor = [aDecoder decodeObjectForKey:MDCButtonUnderlyingColorKey]; + if ([aDecoder containsValueForKey:MDCButtonUnderlyingColorHintKey]) { + self.underlyingColorHint = [aDecoder decodeObjectForKey:MDCButtonUnderlyingColorHintKey]; } if ([aDecoder containsValueForKey:MDCButtonUserElevationsKey]) { @@ -166,9 +168,9 @@ - (void)encodeWithCoder:(NSCoder *)aCoder { } [aCoder encodeBool:_shouldRaiseOnTouch forKey:MDCButtonShouldRaiseOnTouchKey]; - [aCoder encodeBool:_shouldCapitalizeTitle forKey:MDCButtonShouldCapitalizeTitleKey]; - if (_underlyingColor) { - [aCoder encodeObject:_underlyingColor forKey:MDCButtonUnderlyingColorKey]; + [aCoder encodeBool:_uppercaseTitle forKey:MDCButtonUppercaseTitleKey]; + if (_underlyingColorHint) { + [aCoder encodeObject:_underlyingColorHint forKey:MDCButtonUnderlyingColorHintKey]; } [aCoder encodeObject:_userElevations forKey:MDCButtonUserElevationsKey]; } @@ -176,7 +178,7 @@ - (void)encodeWithCoder:(NSCoder *)aCoder { - (void)commonButtonInit { _disabledAlpha = MDCButtonDisabledAlpha; _shouldRaiseOnTouch = YES; - _shouldCapitalizeTitle = YES; + _uppercaseTitle = YES; _userElevations = [NSMutableDictionary dictionary]; _backgroundColors = [NSMutableDictionary dictionary]; _accessibilityLabelForState = [NSMutableDictionary dictionary]; @@ -225,7 +227,7 @@ - (void)commonButtonInit { self.inkColor = [UIColor colorWithWhite:1 alpha:0.2f]; // Uppercase all titles - if (_shouldCapitalizeTitle) { + if (_uppercaseTitle) { [self uppercaseAllTitles]; } } @@ -239,8 +241,8 @@ - (void)setCustomTitleColor:(UIColor *)customTitleColor { [self updateTitleColor]; } -- (void)setUnderlyingColor:(UIColor *)underlyingColor { - _underlyingColor = underlyingColor; +- (void)setUnderlyingColorHint:(UIColor *)underlyingColorHint { + _underlyingColorHint = underlyingColorHint; [self updateTitleColor]; [self updateDisabledTitleColor]; [self updateAlphaAndBackgroundColorAnimated:NO]; @@ -319,15 +321,15 @@ - (void)setEnabled:(BOOL)enabled animated:(BOOL)animated { #pragma mark - Title Uppercasing -- (void)setShouldCapitalizeTitle:(BOOL)shouldCapitalizeTitle { - _shouldCapitalizeTitle = shouldCapitalizeTitle; - if (_shouldCapitalizeTitle) { +- (void)setUppercaseTitle:(BOOL)uppercaseTitle { + _uppercaseTitle = uppercaseTitle; + if (_uppercaseTitle) { [self uppercaseAllTitles]; } } - (void)uppercaseAllTitles { - // This ensures existing titles will get capitalized. + // This ensures existing titles will get uppercased. UIControlState allControlStates = UIControlStateNormal | UIControlStateHighlighted | UIControlStateDisabled | UIControlStateSelected; for (UIControlState state = 0; state <= allControlStates; ++state) { @@ -338,7 +340,7 @@ - (void)uppercaseAllTitles { NSAttributedString *attributedTitle = [self attributedTitleForState:state]; if (attributedTitle) { - [self setAttributedTitle:capitalizeAttributedString(attributedTitle) forState:state]; + [self setAttributedTitle:uppercaseAttributedString(attributedTitle) forState:state]; } } } @@ -352,7 +354,7 @@ - (void)setTitle:(NSString *)title forState:(UIControlState)state { [_accessibilityLabelForState removeObjectForKey:@(state)]; } - if (_shouldCapitalizeTitle) { + if (_uppercaseTitle) { title = [title uppercaseStringWithLocale:[NSLocale currentLocale]]; } [super setTitle:title forState:state]; @@ -367,8 +369,8 @@ - (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState) [_accessibilityLabelForState removeObjectForKey:@(state)]; } - if (_shouldCapitalizeTitle) { - title = capitalizeAttributedString(title); + if (_uppercaseTitle) { + title = uppercaseAttributedString(title); } [super setAttributedTitle:title forState:state]; } @@ -384,7 +386,7 @@ - (void)setAccessibilityLabel:(NSString *)accessibilityLabel { } - (NSString *)accessibilityLabel { - if (!_shouldCapitalizeTitle) { + if (!_uppercaseTitle) { return [super accessibilityLabel]; } @@ -487,11 +489,15 @@ - (UIColor *)currentBackgroundColor { /** The background color that a user would see for this button. If self.backgroundColor is not - transparent, then returns that. Otherwise, returns self.underlyingColor. - @note If self.underlyingColor is not set, then this method will return nil. + transparent, then returns that. Otherwise, returns self.underlyingColorHint. + @note If self.underlyingColorHint is not set, then this method will return nil. */ - (UIColor *)effectiveBackgroundColor { - return ![self isTransparentColor:self.currentBackgroundColor] ? self.currentBackgroundColor : self.underlyingColor; + if (![self isTransparentColor:self.currentBackgroundColor]) { + return self.currentBackgroundColor; + } else { + return self.underlyingColorHint; + } } /** Returns YES if the color is not transparent and is a "dark" color. */ @@ -583,7 +589,7 @@ - (void)updateBackgroundColor { // if (self.enabled) { //// color = self.enabledBackgroundColor; // } else { - // color = [self isDarkColor:_underlyingColor] ? _disabledBackgroundColorLight + // color = [self isDarkColor:_underlyingColorHint] ? _disabledBackgroundColorLight // : _disabledBackgroundColorDark; // } // } @@ -594,7 +600,7 @@ - (void)updateDisabledTitleColor { // Disabled buttons have very low opacity, so we full-opacity text color here to make the text // readable. Also, even for non-flat buttons with opaque backgrounds, the correct background color // to examine is the underlying color, since disabled buttons are so transparent. - BOOL darkBackground = [self isDarkColor:[self underlyingColor]]; + BOOL darkBackground = [self isDarkColor:[self underlyingColorHint]]; [self setTitleColor:darkBackground ? [UIColor whiteColor] : [UIColor blackColor] forState:UIControlStateDisabled]; } @@ -617,4 +623,22 @@ - (void)updateTitleColor { } } +#pragma mark - Deprecations + +- (BOOL)shouldCapitalizeTitle { + return [self isUppercaseTitle]; +} + +- (void)setShouldCapitalizeTitle:(BOOL)shouldCapitalizeTitle { + [self setUppercaseTitle:shouldCapitalizeTitle]; +} + +- (UIColor *)underlyingColor { + return [self underlyingColorHint]; +} + +- (void)setUnderlyingColor:(UIColor *)underlyingColor { + [self setUnderlyingColorHint:underlyingColor]; +} + @end diff --git a/components/Buttons/src/MDCFlatButton.h b/components/Buttons/src/MDCFlatButton.h index cdae3ec6ecf..019f20bab14 100644 --- a/components/Buttons/src/MDCFlatButton.h +++ b/components/Buttons/src/MDCFlatButton.h @@ -21,10 +21,10 @@ /** A "flat" MDCButton. - Flat buttons should be considered the default button. They do not have its own background color - and do not raise when touched. This type of button should be used in most situations requiring a - button. For layouts with many UI elements in which a flat button might get visually lost, - consider using a MDCRaisedButton instead. + Flat buttons should be considered the default button. They do not have their own background color, + do not raise when touched, and have uppercased text to indicate to the user that they are buttons. + Flat buttons should be used in most situations requiring a button. For layouts with many UI + elements in which a flat button might get visually lost, consider using a MDCRaisedButton instead. @see http://www.google.com/design/spec/components/buttons.html#buttons-flat-buttons */ diff --git a/components/Buttons/src/MDCFloatingButton.h b/components/Buttons/src/MDCFloatingButton.h index c68eb84806e..56417e7f73c 100644 --- a/components/Buttons/src/MDCFloatingButton.h +++ b/components/Buttons/src/MDCFloatingButton.h @@ -19,7 +19,12 @@ #import "MDCButton.h" -/** Shapes for material Floating buttons. */ +/** + Shapes for material Floating buttons. + + The mini size should only be used when required for visual continuity with other elements on the + screen. + */ typedef NS_ENUM(NSInteger, MDCFloatingButtonShape) { MDCFloatingButtonShapeDefault, MDCFloatingButtonShapeMini @@ -37,12 +42,12 @@ typedef NS_ENUM(NSInteger, MDCFloatingButtonShape) { @interface MDCFloatingButton : MDCButton /** - Returns a MDCFloatingButton with default colors and the given |shape|. + Returns a MDCFloatingButton with default colors and the given @c shape. @param shape Button shape. @return Button with shape. */ -+ (nonnull instancetype)buttonWithShape:(MDCFloatingButtonShape)shape; ++ (nonnull instancetype)floatingButtonWithShape:(MDCFloatingButtonShape)shape; /** @return The default floating button size dimension. @@ -55,7 +60,7 @@ typedef NS_ENUM(NSInteger, MDCFloatingButtonShape) { + (CGFloat)miniDimension; /** - Initializes self to a button with the given |shape|. + Initializes self to a button with the given @c shape. @param frame Button frame. @param shape Button shape. @@ -74,4 +79,9 @@ typedef NS_ENUM(NSInteger, MDCFloatingButtonShape) { - (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; +#pragma mark - Deprecations + ++ (nonnull instancetype)buttonWithShape:(MDCFloatingButtonShape)shape + __deprecated_msg("Use floatingButtonWithShape: instead."); + @end diff --git a/components/Buttons/src/MDCFloatingButton.m b/components/Buttons/src/MDCFloatingButton.m index 0d638a1e6a9..2d952c33b76 100644 --- a/components/Buttons/src/MDCFloatingButton.m +++ b/components/Buttons/src/MDCFloatingButton.m @@ -39,7 +39,7 @@ + (CGFloat)miniDimension { return MDCFloatingButtonMiniDimension; } -+ (instancetype)buttonWithShape:(MDCFloatingButtonShape)shape { ++ (instancetype)floatingButtonWithShape:(MDCFloatingButtonShape)shape { return [[[self class] alloc] initWithFrame:CGRectZero shape:shape]; } @@ -118,4 +118,10 @@ - (CGFloat)defaultElevationForState:(UIControlState)state { : MDCShadowElevationFABResting); } +#pragma mark - Deprecations + ++ (instancetype)buttonWithShape:(MDCFloatingButtonShape)shape { + return [[self class] floatingButtonWithShape:shape]; +} + @end diff --git a/components/Buttons/tests/unit/ButtonsTests.m b/components/Buttons/tests/unit/ButtonsTests.m index 107a03b3f35..d8677bc6b97 100644 --- a/components/Buttons/tests/unit/ButtonsTests.m +++ b/components/Buttons/tests/unit/ButtonsTests.m @@ -71,7 +71,7 @@ - (void)testUppercaseTitleYes { NSString *originalTitle = @"some Text"; // When - button.shouldCapitalizeTitle = YES; + button.uppercaseTitle = YES; [button setTitle:originalTitle forState:UIControlStateNormal]; // Then @@ -84,7 +84,7 @@ - (void)testUppercaseTitleNo { NSString *originalTitle = @"some Text"; // When - button.shouldCapitalizeTitle = NO; + button.uppercaseTitle = NO; [button setTitle:originalTitle forState:UIControlStateNormal]; // Then @@ -97,9 +97,9 @@ - (void)testUppercaseTitleNoChangedToYes { NSString *originalTitle = @"some Text"; // When - button.shouldCapitalizeTitle = NO; + button.uppercaseTitle = NO; [button setTitle:originalTitle forState:UIControlStateNormal]; - button.shouldCapitalizeTitle = YES; + button.uppercaseTitle = YES; // Then XCTAssertEqualObjects(button.currentTitle, [originalTitle uppercaseStringWithLocale:[NSLocale currentLocale]]); From 105810c544aa6cae8cb69bf58d64c057487cff45 Mon Sep 17 00:00:00 2001 From: Adrian Secord Date: Thu, 7 Apr 2016 10:39:23 -0400 Subject: [PATCH 08/92] Exposed ink style and max ripple radius and modified MDCButtonBarButton. Summary: Fixes https://github.com/google/material-components-ios/issues/228. Reviewers: #mdc_ios_owners, featherless Reviewed By: #mdc_ios_owners, featherless Projects: #material_components_ios Differential Revision: http://codereview.cc/D507 --- .../src/private/MDCAppBarButtonBarBuilder.m | 8 ++++- components/Buttons/src/MDCButton.h | 11 +++++++ components/Buttons/src/MDCButton.m | 32 +++++++++++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m b/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m index 1fc300ba890..0a8654b4ba0 100644 --- a/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m +++ b/components/ButtonBar/src/private/MDCAppBarButtonBarBuilder.m @@ -94,6 +94,7 @@ - (UIView *)buttonBar:(MDCButtonBar *)buttonBar MDCButtonBarButton *button = [[MDCButtonBarButton alloc] init]; [button setBackgroundColor:nil forState:UIControlStateNormal]; + button.inkStyle = MDCInkStyleUnbounded; button.disabledAlpha = kDisabledButtonAlpha; button.exclusiveTouch = YES; @@ -110,7 +111,7 @@ - (UIView *)buttonBar:(MDCButtonBar *)buttonBar button.tag = buttonItem.tag; button.customTitleColor = self.buttonTitleColor; - [button setUnderlyingColor:self.buttonUnderlyingColor]; + [button setUnderlyingColorHint:self.buttonUnderlyingColor]; [self updateButton:button withItem:buttonItem barMetrics:UIBarMetricsDefault]; @@ -237,6 +238,11 @@ - (CGSize)sizeThatFits:(CGSize)size { return fitSize; } +- (void)layoutSubviews { + [super layoutSubviews]; + self.inkMaxRippleRadius = MIN(self.bounds.size.width, self.bounds.size.height) / 2; +} + @end @implementation UIBarButtonItem (MDCHeaderInternal) diff --git a/components/Buttons/src/MDCButton.h b/components/Buttons/src/MDCButton.h index d9ddb9c41bc..a7e2c531373 100644 --- a/components/Buttons/src/MDCButton.h +++ b/components/Buttons/src/MDCButton.h @@ -17,6 +17,8 @@ #import #import +#import "MaterialInk.h" + /** A Material flat, raised or floating button. @@ -51,9 +53,18 @@ */ - (void)setBackgroundColor:(nullable UIColor *)backgroundColor forState:(UIControlState)state; +/** The ink style of the button. */ +@property(nonatomic, assign) MDCInkStyle inkStyle; + /** The ink color of the button. */ @property(nonatomic, strong, null_resettable) UIColor *inkColor; +/* + Maximum radius of the button's ink. If the radius <= 0 then half the length of the diagonal of + self.bounds is used. + */ +@property(nonatomic, assign) CGFloat inkMaxRippleRadius; + /** A custom title color for the non-disabled states. The default is nil, which means that the button chooses its title color automatically based on |underlyingColor|, whether the button is opaque, diff --git a/components/Buttons/src/MDCButton.m b/components/Buttons/src/MDCButton.m index 2ae3597a09d..8f0c8efaa22 100644 --- a/components/Buttons/src/MDCButton.m +++ b/components/Buttons/src/MDCButton.m @@ -34,7 +34,10 @@ @"MDCButtonDisabledBackgroundColorLightKey"; static NSString *const MDCButtonDisabledBackgroundColorDarkKey = @"MDCButtonDisabledBackgroundColorDarkKey"; +static NSString *const MDCButtonInkViewInkStyleKey = @"MDCButtonInkViewInkStyleKey"; static NSString *const MDCButtonInkViewInkColorKey = @"MDCButtonInkViewInkColorKey"; +static NSString *const MDCButtonInkViewInkMaxRippleRadiusKey = + @"MDCButtonInkViewInkMaxRippleRadiusKey"; static NSString *const MDCButtonShouldRaiseOnTouchKey = @"MDCButtonShouldRaiseOnTouchKey"; // Previous value kept for backwards compatibility. static NSString *const MDCButtonUppercaseTitleKey = @"MDCButtonShouldCapitalizeTitleKey"; @@ -135,10 +138,19 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { // self.disabledBackgroundColorDark = // [aDecoder decodeObjectForKey:MDCButtonDisabledBackgroundColorDarkKey]; // } + if ([aDecoder containsValueForKey:MDCButtonInkViewInkStyleKey]) { + self.inkView.inkStyle = [aDecoder decodeIntegerForKey:MDCButtonInkViewInkStyleKey]; + } + if ([aDecoder containsValueForKey:MDCButtonInkViewInkColorKey]) { self.inkView.inkColor = [aDecoder decodeObjectForKey:MDCButtonInkViewInkColorKey]; } + if ([aDecoder containsValueForKey:MDCButtonInkViewInkMaxRippleRadiusKey]) { + self.inkView.maxRippleRadius = + [aDecoder decodeDoubleForKey:MDCButtonInkViewInkMaxRippleRadiusKey]; + } + if ([aDecoder containsValueForKey:MDCButtonShouldRaiseOnTouchKey]) { self.shouldRaiseOnTouch = [aDecoder decodeBoolForKey:MDCButtonShouldRaiseOnTouchKey]; } @@ -163,10 +175,12 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { - (void)encodeWithCoder:(NSCoder *)aCoder { [super encodeWithCoder:aCoder]; + [aCoder encodeInteger:_inkView.inkStyle forKey:MDCButtonInkViewInkStyleKey]; if (_inkView.inkColor) { [aCoder encodeObject:_inkView.inkColor forKey:MDCButtonInkViewInkColorKey]; } + [aCoder encodeDouble:_inkView.maxRippleRadius forKey:MDCButtonInkViewInkMaxRippleRadiusKey]; [aCoder encodeBool:_shouldRaiseOnTouch forKey:MDCButtonShouldRaiseOnTouchKey]; [aCoder encodeBool:_uppercaseTitle forKey:MDCButtonUppercaseTitleKey]; if (_underlyingColorHint) { @@ -203,8 +217,6 @@ - (void)commonButtonInit { // Set up ink layer. _inkView = [[MDCInkView alloc] initWithFrame:self.bounds]; - - _inkView.maxRippleRadius = 0; [self insertSubview:_inkView belowSubview:self.imageView]; // UIButton has a drag enter/exit boundary that is outside of the frame of the button itself. @@ -419,6 +431,14 @@ - (UIAccessibilityTraits)accessibilityTraits { #pragma mark - Ink +- (MDCInkStyle)inkStyle { + return _inkView.inkStyle; +} + +- (void)setInkStyle:(MDCInkStyle)inkStyle { + _inkView.inkStyle = inkStyle; +} + - (UIColor *)inkColor { return _inkView.inkColor; } @@ -427,6 +447,14 @@ - (void)setInkColor:(UIColor *)inkColor { _inkView.inkColor = inkColor; } +- (CGFloat)inkMaxRippleRadius { + return _inkView.maxRippleRadius; +} + +- (void)setInkMaxRippleRadius:(CGFloat)inkMaxRippleRadius { + _inkView.maxRippleRadius = inkMaxRippleRadius; +} + #pragma mark - Shadows - (MDCShadowLayer *)shadowLayer { From 5fa91b67cd3bb8e1c0d91fd44b96acd3a0e9f7e8 Mon Sep 17 00:00:00 2001 From: Ian Gordon Date: Fri, 25 Mar 2016 16:57:34 -0400 Subject: [PATCH 09/92] [ThumbTrack] Re-enable Ink Reviewers: randallli, #mdc_ios_owners, ajsecord Reviewed By: #mdc_ios_owners, ajsecord Subscribers: ajsecord Projects: #material_components_ios Differential Revision: http://codereview.cc/D363 --- components/Slider/src/MDCSlider.m | 3 +- components/Switch/src/MDCSwitch.m | 1 - .../private/ThumbTrack/src/MDCThumbTrack.m | 54 +++++++++---------- 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/components/Slider/src/MDCSlider.m b/components/Slider/src/MDCSlider.m index c903875cb25..3a783051e61 100644 --- a/components/Slider/src/MDCSlider.m +++ b/components/Slider/src/MDCSlider.m @@ -22,7 +22,6 @@ static const CGFloat kSliderFrameHeight = 27.0f; static const CGFloat kSliderMinTouchSize = 48.0f; static const CGFloat kSliderThumbRadius = 6.0f; -static const CGFloat kSliderThumbMaxRippleRadius = 16.0f; static const CGFloat kSliderAccessibilityIncrement = 0.1f; // Matches UISlider's percent increment. static const CGFloat kSliderLightThemeTrackAlpha = 0.26f; @@ -68,7 +67,7 @@ - (void)commonMDCSliderInit { _thumbTrack.disabledTrackHasThumbGaps = YES; _thumbTrack.trackEndsAreInset = YES; _thumbTrack.thumbRadius = kSliderThumbRadius; - _thumbTrack.thumbMaxRippleRadius = kSliderThumbMaxRippleRadius; + _thumbTrack.shouldDisplayInk = NO; _thumbTrack.trackOffColor = [[self class] defaultTrackOffColor]; _thumbTrack.thumbDisabledColor = [[self class] defaultDisabledColor]; _thumbTrack.trackDisabledColor = [[self class] defaultDisabledColor]; diff --git a/components/Switch/src/MDCSwitch.m b/components/Switch/src/MDCSwitch.m index 045eb4b42f8..e4de2786592 100644 --- a/components/Switch/src/MDCSwitch.m +++ b/components/Switch/src/MDCSwitch.m @@ -66,7 +66,6 @@ - (void)commonMDCSwitchInitWithColor:(UIColor *)color { _thumbTrack.thumbView.hasShadow = YES; _thumbTrack.panningAllowedOnEntireControl = YES; _thumbTrack.tapsAllowedOnThumb = YES; - _thumbTrack.shouldDisplayInk = NO; _thumbTrack.delegate = self; [self addSubview:_thumbTrack]; diff --git a/components/private/ThumbTrack/src/MDCThumbTrack.m b/components/private/ThumbTrack/src/MDCThumbTrack.m index 826634c55f0..749ec529ef9 100644 --- a/components/private/ThumbTrack/src/MDCThumbTrack.m +++ b/components/private/ThumbTrack/src/MDCThumbTrack.m @@ -16,6 +16,7 @@ #import "MDCThumbTrack.h" +#import "MaterialInk.h" #import "MDCThumbView.h" #import "UIColor+MDC.h" @@ -76,9 +77,8 @@ static inline CGFloat DistanceFromPointToPoint(CGPoint point1, CGPoint point2) { return CGHypot(point1.x - point2.x, point1.y - point2.y); } -// TODO(iangordon): Re-enable Ink -//@interface MDCThumbTrack () -//@end +@interface MDCThumbTrack () +@end @implementation MDCThumbTrack { UIPanGestureRecognizer *_panRecognizer; @@ -88,8 +88,7 @@ @implementation MDCThumbTrack { UIColor *_thumbOnColor; UIColor *_trackOnColor; UIColor *_clearColor; - // TODO(iangordon): Re-enable Ink - // QTMInkTouchController *_touchController; + MDCInkTouchController *_touchController; UIView *_trackView; CAShapeLayer *_trackMaskLayer; CALayer *_trackOnLayer; @@ -142,14 +141,13 @@ - (instancetype)initWithFrame:(CGRect)frame onTintColor:(UIColor *)onTintColor { _panRecognizer.cancelsTouchesInView = NO; [self updatePanRecognizerTarget]; - // TODO(iangordon): Re-enable Ink - // // Set up ink layer. - // _touchController = [[QTMInkTouchController alloc] initWithTouchableView:_thumbView - // backgroundColorGroup:colorGroup - // delegate:nil]; - // _touchController.inkView.clipsRippleToBounds = NO; - // _touchController.inkView.fillsBackgroundOnSpread = NO; - // _touchController.delegate = self; + // Set up ink layer. + _touchController = [[MDCInkTouchController alloc] initWithView:_thumbView]; + _touchController.delegate = self; + + [_touchController addInkView]; + + _touchController.inkView.inkStyle = MDCInkStyleUnbounded; // Set colors. if (onTintColor == nil) { @@ -187,8 +185,7 @@ - (void)setPrimaryColor:(UIColor *)primaryColor { ? [primaryColor colorWithAlphaComponent:kTrackOnAlpha] : primaryColor; - // TODO(iangordon): Remove ColorGroup support - // [_touchController.inkView setBackgroundColorGroup:colorGroup]; + [_touchController.inkView setInkColor:[primaryColor colorWithAlphaComponent:kTrackOnAlpha]]; [self updateColorsAnimated:NO withDuration:0.0f]; } @@ -288,14 +285,13 @@ - (void)setThumbRadius:(CGFloat)thumbRadius { [self setNeedsLayout]; } -// TODO(iangordon): Re-enable Ink -//- (CGFloat)thumbMaxRippleRadius { -// return _touchController.inkView.maxRippleRadius; -//} -// -//- (void)setThumbMaxRippleRadius:(CGFloat)thumbMaxRippleRadius { -// _touchController.inkView.maxRippleRadius = thumbMaxRippleRadius; -//} +- (CGFloat)thumbMaxRippleRadius { + return _touchController.inkView.maxRippleRadius; +} + +- (void)setThumbMaxRippleRadius:(CGFloat)thumbMaxRippleRadius { + _touchController.inkView.maxRippleRadius = thumbMaxRippleRadius; +} - (CGPoint)thumbPosition { return _thumbView.center; @@ -331,12 +327,12 @@ - (void)setEnabled:(BOOL)enabled { [self updateColorsAnimated:NO withDuration:0.0f]; } -// TODO(iangordon): Re-enable Ink -//#pragma mark - QTMInkTouchControllerDelegate -// -//- (BOOL)shouldInkTouchControllerProcessInkTouches:(QTMInkTouchController *)inkTouchController { -// return _shouldDisplayInk; -//} +#pragma mark - MDCInkTouchControllerDelegate + +- (BOOL)inkTouchController:(nonnull MDCInkTouchController *)inkTouchController + shouldProcessInkTouchesAtTouchLocation:(CGPoint)location { + return _shouldDisplayInk; +} #pragma mark - Private From 2e247f2977456fad0b470f7329f0c61439a8347f Mon Sep 17 00:00:00 2001 From: Adrian Secord Date: Thu, 7 Apr 2016 10:43:09 -0400 Subject: [PATCH 10/92] Renamed commonInit methods. Summary: Fixes https://github.com/google/material-components-ios/issues/159. Reviewers: featherless, #mdc_ios_owners Reviewed By: featherless, #mdc_ios_owners Subscribers: featherless Projects: #material_components_ios Differential Revision: http://codereview.cc/D508 --- components/ButtonBar/src/MDCButtonBar.m | 6 +++--- components/Buttons/src/MDCFlatButton.m | 6 +++--- components/NavigationBar/src/MDCNavigationBar.m | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/ButtonBar/src/MDCButtonBar.m b/components/ButtonBar/src/MDCButtonBar.m index 0780e63b701..1402a7ce5a3 100644 --- a/components/ButtonBar/src/MDCButtonBar.m +++ b/components/ButtonBar/src/MDCButtonBar.m @@ -42,7 +42,7 @@ - (void)dealloc { self.items = nil; } -- (void)commonInit { +- (void)commonMDCButtonBarInit { _buttonItemsLock = [[NSObject alloc] init]; _defaultBuilder = [[MDCAppBarButtonBarBuilder alloc] init]; @@ -56,7 +56,7 @@ - (void)commonInit { - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - [self commonInit]; + [self commonMDCButtonBarInit]; } return self; } @@ -64,7 +64,7 @@ - (instancetype)initWithFrame:(CGRect)frame { - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { - [self commonInit]; + [self commonMDCButtonBarInit]; } return self; } diff --git a/components/Buttons/src/MDCFlatButton.m b/components/Buttons/src/MDCFlatButton.m index 8956d6b1e98..a88059b250e 100644 --- a/components/Buttons/src/MDCFlatButton.m +++ b/components/Buttons/src/MDCFlatButton.m @@ -29,7 +29,7 @@ @implementation MDCFlatButton - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - [self commonInit]; + [self commonMDCFlatButtonInit]; } return self; } @@ -40,12 +40,12 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { if ([aDecoder containsValueForKey:MDCFlatButtonHasOpaqueBackground]) { self.hasOpaqueBackground = [aDecoder decodeBoolForKey:MDCFlatButtonHasOpaqueBackground]; } - [self commonInit]; + [self commonMDCFlatButtonInit]; } return self; } -- (void)commonInit { +- (void)commonMDCFlatButtonInit { self.shouldRaiseOnTouch = NO; [self setBackgroundColor:nil forState:UIControlStateNormal]; self.inkColor = [UIColor colorWithWhite:0 alpha:0.06f]; diff --git a/components/NavigationBar/src/MDCNavigationBar.m b/components/NavigationBar/src/MDCNavigationBar.m index cda44a60927..56a7ab852a5 100644 --- a/components/NavigationBar/src/MDCNavigationBar.m +++ b/components/NavigationBar/src/MDCNavigationBar.m @@ -113,7 +113,7 @@ - (void)dealloc { [self setObservedNavigationItem:nil]; } -- (void)commonInit { +- (void)commonMDCNavigationBarInit { _observedNavigationItemLock = [[NSObject alloc] init]; _titleLabel = [[UILabel alloc] init]; @@ -131,7 +131,7 @@ - (void)commonInit { - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { - [self commonInit]; + [self commonMDCNavigationBarInit]; } return self; } @@ -139,7 +139,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - [self commonInit]; + [self commonMDCNavigationBarInit]; } return self; } From 363a766c94b8157f6030d084be0c934681f7cb1d Mon Sep 17 00:00:00 2001 From: Ian Gordon Date: Wed, 6 Apr 2016 17:20:25 -0400 Subject: [PATCH 11/92] [Buttons] Update example Summary: Remove unnecessary sizing of storyboard buttons. Fix spacing for programmatic buttons. Change floating labell to match. Reviewers: #mdc_ios_owners, ajsecord Reviewed By: #mdc_ios_owners, ajsecord Projects: #material_components_ios Differential Revision: http://codereview.cc/D499 --- .../Buttons/examples/ButtonsStoryboardAndProgrammatic.swift | 6 +----- .../resources/ButtonsStoryboardAndProgrammatic.storyboard | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift b/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift index dee864aa6ec..fb70480c191 100644 --- a/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift +++ b/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift @@ -46,10 +46,6 @@ class ButtonsStoryboardAndProgrammaticController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - storyboardRaised.sizeToFit() - storyboardFlat.sizeToFit() - storyboardFloating.sizeToFit() - raisedButton.setTitle("Programmatic", forState: .Normal) raisedButton.sizeToFit() raisedButton.translatesAutoresizingMaskIntoConstraints = false @@ -91,7 +87,7 @@ class ButtonsStoryboardAndProgrammaticController: UIViewController { toItem: self.view, attribute: .Top, multiplier: 1.0, - constant: 86.0)) + constant: 22.0)) self.view.addConstraints( NSLayoutConstraint.constraintsWithVisualFormat("V:[raised]-22-[flat]-22-[floating]", diff --git a/components/Buttons/examples/resources/ButtonsStoryboardAndProgrammatic.storyboard b/components/Buttons/examples/resources/ButtonsStoryboardAndProgrammatic.storyboard index 54719d029ee..abb27f6320f 100644 --- a/components/Buttons/examples/resources/ButtonsStoryboardAndProgrammatic.storyboard +++ b/components/Buttons/examples/resources/ButtonsStoryboardAndProgrammatic.storyboard @@ -28,7 +28,7 @@