From 09683a025c17c43137fdc846ec0b84740e9d7dbc Mon Sep 17 00:00:00 2001 From: Yiran Mao Date: Wed, 1 Jun 2016 13:42:10 -0700 Subject: [PATCH 01/28] Add links to github on homepage. Close https://github.com/google/material-components-ios/issues/528 --- site-index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/site-index.md b/site-index.md index 27ecc16551f..716a68cbcd7 100644 --- a/site-index.md +++ b/site-index.md @@ -13,6 +13,7 @@ An easy way to create beautiful apps with modular and customizable UI compo [Get Started](#quickstart) +[View on GitHub](https://github.com/google/material-components-ios) @@ -139,5 +140,8 @@ An easy way to create beautiful apps with modular and customizable UI compo - [Explore our Code Samples]({{ site.folder }}/howto/tutorial/#sample-code) + + - [View the project on Github](https://github.com/google/material-components-ios/) + From 1c0bfe8cea383c8fe126d6cebf938a6683b92bc7 Mon Sep 17 00:00:00 2001 From: randallli Date: Thu, 2 Jun 2016 13:31:53 -0400 Subject: [PATCH 02/28] [Collections] Fixed podspec to include more frameworks needed by the component Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D929 --- MaterialComponents.podspec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MaterialComponents.podspec b/MaterialComponents.podspec index 3125d937559..2db94f44f78 100644 --- a/MaterialComponents.podspec +++ b/MaterialComponents.podspec @@ -80,6 +80,8 @@ Pod::Spec.new do |s| ss.source_files = "components/#{ss.base_name}/src/*.{h,m}", "components/#{ss.base_name}/src/private/*.{h,m}" ss.header_mappings_dir = "components/#{ss.base_name}/src" + ss.framework = "CoreGraphics", "QuartzCore" + ss.dependency "MaterialComponents/CollectionLayoutAttributes" ss.dependency "MaterialComponents/Ink" ss.dependency "MaterialComponents/Typography" @@ -105,6 +107,8 @@ Pod::Spec.new do |s| "Material#{ss.base_name}" => ["components/#{ss.base_name}/src/Material#{ss.base_name}.bundle/*"] } + ss.framework = "CoreGraphics", "QuartzCore" + ss.dependency "MaterialComponents/CollectionCells" ss.dependency "MaterialComponents/CollectionLayoutAttributes" ss.dependency "MaterialComponents/Ink" @@ -221,7 +225,7 @@ Pod::Spec.new do |s| end s.subspec "private" do |pss| - + # Pull in icon dependencies # The implementation of this method is generated by running scripts/sync_icons.sh # and defined in scripts/generated/icons.rb From 306da8d238cfd9d85f65ccb33370e1c6485418a1 Mon Sep 17 00:00:00 2001 From: Chris Cox Date: Fri, 3 Jun 2016 10:12:57 -0400 Subject: [PATCH 03/28] [Collections] Fixes bug when initializing collection view with own layout. Reviewers: ajsecord, O1 Material components iOS, randallli Reviewed By: O1 Material components iOS, randallli Tags: #material_components_ios Differential Revision: http://codereview.cc/D930 --- components/Collections/src/MDCCollectionViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Collections/src/MDCCollectionViewController.m b/components/Collections/src/MDCCollectionViewController.m index 1e2fe5eb906..bd900cb4beb 100644 --- a/components/Collections/src/MDCCollectionViewController.m +++ b/components/Collections/src/MDCCollectionViewController.m @@ -48,7 +48,7 @@ @implementation MDCCollectionViewController { - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout { self = [super initWithCollectionViewLayout:layout]; if (self) { - [self commonMDCCollectionViewControllerInit:self.collectionViewLayout]; + [self commonMDCCollectionViewControllerInit:layout]; } return self; } From e22c4dd1336fee596190f4237f3a2df582eae786 Mon Sep 17 00:00:00 2001 From: randallli Date: Fri, 3 Jun 2016 10:56:01 -0400 Subject: [PATCH 04/28] ran ./scripts/release/manage_pods.py install Reviewers: ajsecord, O1 Material components iOS Reviewed By: ajsecord, O1 Material components iOS Tags: #material_components_ios Differential Revision: http://codereview.cc/D931 --- catalog/Podfile.lock | 2 +- demos/Pesto/Podfile.lock | 2 +- demos/Shrine/Podfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/catalog/Podfile.lock b/catalog/Podfile.lock index 7d714a304bf..7c28423885a 100644 --- a/catalog/Podfile.lock +++ b/catalog/Podfile.lock @@ -127,7 +127,7 @@ EXTERNAL SOURCES: :path: ../ SPEC CHECKSUMS: - MaterialComponents: 1ba34edf996dbdf6acaea8b3051b5d78ab9d252f + MaterialComponents: c368e132f1750211ec982d3b4c844d2886a785e0 MaterialComponentsCatalog: c665fdd39bff9621608cec8fe0a99e44ce8e7a13 MaterialComponentsUnitTests: 66c55d81bb08daf37915f7142244bfeaa04a4776 diff --git a/demos/Pesto/Podfile.lock b/demos/Pesto/Podfile.lock index 935a8ca6b9c..146f5aa796b 100644 --- a/demos/Pesto/Podfile.lock +++ b/demos/Pesto/Podfile.lock @@ -117,7 +117,7 @@ EXTERNAL SOURCES: :path: ../../ SPEC CHECKSUMS: - MaterialComponents: 1ba34edf996dbdf6acaea8b3051b5d78ab9d252f + MaterialComponents: c368e132f1750211ec982d3b4c844d2886a785e0 PODFILE CHECKSUM: f138be16d4835113ff672258fc7529fad3f90e91 diff --git a/demos/Shrine/Podfile.lock b/demos/Shrine/Podfile.lock index 93b8f4ed911..66768e7a6d7 100644 --- a/demos/Shrine/Podfile.lock +++ b/demos/Shrine/Podfile.lock @@ -117,7 +117,7 @@ EXTERNAL SOURCES: :path: ../../ SPEC CHECKSUMS: - MaterialComponents: 1ba34edf996dbdf6acaea8b3051b5d78ab9d252f + MaterialComponents: c368e132f1750211ec982d3b4c844d2886a785e0 PODFILE CHECKSUM: b585ca32a2884e050823cc1f861e8b7246f7dcc1 From 77d8ebcd78cf37b9e38b77c5b29136ee37d6f719 Mon Sep 17 00:00:00 2001 From: randallli Date: Fri, 3 Jun 2016 11:27:17 -0400 Subject: [PATCH 05/28] [FontDiskLoader] Added unregisterFont method. Reviewers: ajsecord, O1 Material components iOS Reviewed By: ajsecord, O1 Material components iOS Subscribers: ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D903 --- .../FontDiskLoader/src/MDCFontDiskLoader.h | 6 ++- .../FontDiskLoader/src/MDCFontDiskLoader.m | 15 ++++++++ .../tests/unit/FontDiskLoaderTests.m | 38 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.h b/components/FontDiskLoader/src/MDCFontDiskLoader.h index 71409c789aa..81a1f56a7bc 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.h +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.h @@ -59,10 +59,14 @@ Attempts to register the font. The @c isRegistered and @c hasFailedRegistration flags reflect the results of this registration - attempt. Returns the value of isRegistered. + attempt. Returns true if the font is registered. If font registration fails, subsequent calls to + registerFont will fail unless unregisterFont is called first. */ - (BOOL)registerFont; +/** Attempts to unregister the font. Returns true when the font is unregistered. */ +- (BOOL)unregisterFont; + #pragma mark Accessing the font's registration status /** The registered state of the custom font. */ diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.m b/components/FontDiskLoader/src/MDCFontDiskLoader.m index d13877ec45e..0383bbfe8c3 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.m +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.m @@ -82,6 +82,21 @@ - (BOOL)registerFont { return _isRegistered; } +- (BOOL)unregisterFont { + if (!_isRegistered) { + _hasFailedRegistration = NO; + return !_isRegistered; // Is already not registered + } + CFErrorRef error = NULL; + _isRegistered = !CTFontManagerUnregisterFontsForURL((__bridge CFURLRef)self.fontURL, + kCTFontManagerScopeProcess, + &error); + if (_isRegistered || error) { + NSLog(@"Failed to unregister font: %@", error); + } + return !_isRegistered; +} + - (UIFont *)fontOfSize:(CGFloat)fontSize { [self registerFont]; return [UIFont fontWithName:self.fontName size:fontSize]; diff --git a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m index 0b2198f9d8c..5bcaa898537 100644 --- a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m +++ b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m @@ -74,6 +74,44 @@ - (void)testRegisterFont { XCTAssertTrue(resource.isRegistered); } +- (void)testUnregisterFont { + // Given + MDCFontDiskLoader *resource = [self validResource]; + [resource registerFont]; + + // When + BOOL success = [resource unregisterFont]; + + // Then + XCTAssertFalse(resource.isRegistered); + XCTAssertTrue(success); +} + +- (void)testUnregisterFailedRegistration { + // Given + MDCFontDiskLoader *resource = [self invalidResource]; + [resource registerFont]; + + // When + [resource unregisterFont]; + + // Then + XCTAssertFalse(resource.isRegistered); + XCTAssertFalse(resource.hasFailedRegistration); +} + +- (void)testUnregisterNotRegistered { + // Given + MDCFontDiskLoader *resource = [self invalidResource]; + + // When + [resource unregisterFont]; + + // Then + XCTAssertFalse(resource.isRegistered); + XCTAssertFalse(resource.hasFailedRegistration); +} + - (void)testRegisterFontFailure { // Given MDCFontDiskLoader *resource = [self invalidResource]; From 7a0a9f0aaa61d47a780fd404916701f373f7e53d Mon Sep 17 00:00:00 2001 From: randallli Date: Thu, 26 May 2016 14:08:43 -0400 Subject: [PATCH 06/28] [MDCFontDiskLoader] Added copying protocol Reviewers: featherless, O1 Material components iOS Reviewed By: featherless, O1 Material components iOS Tags: #material_components_ios Differential Revision: http://codereview.cc/D909 --- components/FontDiskLoader/src/MDCFontDiskLoader.h | 2 +- components/FontDiskLoader/src/MDCFontDiskLoader.m | 4 ++++ .../FontDiskLoader/tests/unit/FontDiskLoaderTests.m | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.h b/components/FontDiskLoader/src/MDCFontDiskLoader.h index 81a1f56a7bc..bf21958d807 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.h +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.h @@ -17,7 +17,7 @@ #import /** Register and load a custom font resource. */ -@interface MDCFontDiskLoader : NSObject +@interface MDCFontDiskLoader : NSObject #pragma mark Creating a font resource diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.m b/components/FontDiskLoader/src/MDCFontDiskLoader.m index 0383bbfe8c3..2c15573e2c3 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.m +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.m @@ -127,4 +127,8 @@ - (NSUInteger)hash { return self.fontName.hash ^ self.fontURL.hash; } +- (id)copyWithZone:(NSZone *)zone { + return self; +} + @end diff --git a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m index 5bcaa898537..899b8b38b27 100644 --- a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m +++ b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m @@ -123,6 +123,17 @@ - (void)testRegisterFontFailure { XCTAssertTrue(resource.hasFailedRegistration); } +- (void)testCopy { + // Given + MDCFontDiskLoader *loader = [self validResource]; + + // When + MDCFontDiskLoader *secondFontLoader = [loader copy]; + + // Then + XCTAssertEqualObjects(loader, secondFontLoader); +} + - (void)testProvidesACustomFont { // Given MDCFontDiskLoader *resource = [self validResource]; @@ -233,4 +244,5 @@ - (void)testEquals { XCTAssertEqualObjects(loader, secondLoader); XCTAssertEqual([loader hash], [secondLoader hash]); } + @end From 1ef21ea7e080664050271576fd85dcea3c4d87b4 Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 25 May 2016 17:49:28 -0400 Subject: [PATCH 07/28] [MDCFontDiskLoader] sharing registered state across all instances of objects. Summary: When two font loaders are created with the same url file if one is registered/unregistered the other will also be considered registered/unregistered. This is shared across all instances of the fileURL. Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Subscribers: ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D910 --- .../FontDiskLoader/src/MDCFontDiskLoader.h | 32 +++++++++-- .../FontDiskLoader/src/MDCFontDiskLoader.m | 56 ++++++++++++++----- .../tests/unit/FontDiskLoaderTests.m | 14 +++++ 3 files changed, 84 insertions(+), 18 deletions(-) diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.h b/components/FontDiskLoader/src/MDCFontDiskLoader.h index bf21958d807..dc31baf307d 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.h +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.h @@ -16,7 +16,15 @@ #import -/** Register and load a custom font resource. */ +/** + Register and load a custom font resource. + + This class provides a convenience layer on top of CoreText APIs. Registration occurs by @c fileURL, + therefore registration state is shared across all instances of MDCFontDiskLoader objects. For + example if two MDCFontDiskLoader objects have the same fileURL, calling @c registerFont one will + also alter the state of the second MDCFontDiskLoader object. The same holds true for + @c unregisterFont. + */ @interface MDCFontDiskLoader : NSObject #pragma mark Creating a font resource @@ -58,21 +66,37 @@ /** Attempts to register the font. + All instances of MDCFontDiskLoader with the same fontURL will reflect changes from this method. + The @c isRegistered and @c hasFailedRegistration flags reflect the results of this registration attempt. Returns true if the font is registered. If font registration fails, subsequent calls to registerFont will fail unless unregisterFont is called first. */ - (BOOL)registerFont; -/** Attempts to unregister the font. Returns true when the font is unregistered. */ +/** + Attempts to unregister the font. + + All instances of MDCFontDiskLoader with the same fontURL will reflect changes from this method. + + Returns true when the font is unregistered. Resets @c hasFailedRegistration back to false. + */ - (BOOL)unregisterFont; #pragma mark Accessing the font's registration status -/** The registered state of the custom font. */ +/** + The registered state of the custom font. + + All instances of MDCFontDiskLoader with the same fontURL have the same value of @c isRegistered. + */ @property(nonatomic) BOOL isRegistered; -/** This flag is true when the registration failed. It prevents future attempts at registration. */ +/** + This flag is true when the registration failed. + + It prevents future attempts at registration. To reset call @c unregisterFont. + */ @property(nonatomic) BOOL hasFailedRegistration; #pragma mark Requesting fonts of a given size diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.m b/components/FontDiskLoader/src/MDCFontDiskLoader.m index 2c15573e2c3..273f8390235 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.m +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.m @@ -22,6 +22,8 @@ @interface MDCFontDiskLoader () @property(nonatomic, strong) NSURL *fontURL; @end +static NSMutableSet *registeredFonts; + @implementation MDCFontDiskLoader - (instancetype)initWithName:(NSString *)fontName URL:(NSURL *)fontURL { @@ -49,7 +51,7 @@ - (instancetype)initWithFontName:(NSString *)fontName } - (BOOL)registerFont { - if (_isRegistered) { + if (self.isRegistered) { return YES; } if (_hasFailedRegistration) { @@ -61,16 +63,16 @@ - (BOOL)registerFont { return NO; } CFErrorRef error = NULL; - _isRegistered = CTFontManagerRegisterFontsForURL((__bridge CFURLRef)self.fontURL, - kCTFontManagerScopeProcess, - &error); - if (!_isRegistered) { + self.isRegistered = CTFontManagerRegisterFontsForURL((__bridge CFURLRef)self.fontURL, + kCTFontManagerScopeProcess, + &error); + if (!self.isRegistered) { if (error && CFErrorGetCode(error) == kCTFontManagerErrorAlreadyRegistered) { // If it's already been loaded by somebody else, we don't care. // We do not check the error domain to make sure they match because // kCTFontManagerErrorDomain is not defined in the iOS 8 SDK. // Radar 18651170 iOS 8 SDK missing definition for kCTFontManagerErrorDomain - _isRegistered = YES; + self.isRegistered = YES; } else { NSLog(@"Failed to load font: %@", error); _hasFailedRegistration = YES; @@ -79,22 +81,22 @@ - (BOOL)registerFont { if (error) { CFRelease(error); } - return _isRegistered; + return self.isRegistered; } - (BOOL)unregisterFont { - if (!_isRegistered) { + if (!self.isRegistered) { _hasFailedRegistration = NO; - return !_isRegistered; // Is already not registered + return YES; } CFErrorRef error = NULL; - _isRegistered = !CTFontManagerUnregisterFontsForURL((__bridge CFURLRef)self.fontURL, - kCTFontManagerScopeProcess, - &error); - if (_isRegistered || error) { + self.isRegistered = !CTFontManagerUnregisterFontsForURL((__bridge CFURLRef)self.fontURL, + kCTFontManagerScopeProcess, + &error); + if (self.isRegistered || error) { NSLog(@"Failed to unregister font: %@", error); } - return !_isRegistered; + return !self.isRegistered; } - (UIFont *)fontOfSize:(CGFloat)fontSize { @@ -131,4 +133,30 @@ - (id)copyWithZone:(NSZone *)zone { return self; } +- (BOOL)isRegistered { + @synchronized(registeredFonts) { + return [registeredFonts containsObject:self.fontURL]; + } +} + +- (void)setIsRegistered:(BOOL)isRegistered { + @synchronized(registeredFonts) { + if (isRegistered == [registeredFonts containsObject:self.fontURL]) { + return; // Already in the correct state; + } + if (isRegistered) { + [registeredFonts addObject:self.fontURL]; + } else { + [registeredFonts removeObject:self.fontURL]; + } + } +} + ++ (void)load { + static dispatch_once_t once; + dispatch_once(&once, ^{ + registeredFonts = [[NSMutableSet alloc] init]; + }); +} + @end diff --git a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m index 899b8b38b27..452f04abe5c 100644 --- a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m +++ b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m @@ -134,6 +134,20 @@ - (void)testCopy { XCTAssertEqualObjects(loader, secondFontLoader); } +- (void)testIsRegisteredOfSecondFontLoader { + // Given + MDCFontDiskLoader *loader = [self validResource]; + MDCFontDiskLoader *secondFontLoader = + [[MDCFontDiskLoader alloc] initWithName:loader.fontName + URL:loader.fontURL]; + + // When + [loader registerFont]; + + // Then + XCTAssertEqual(loader.isRegistered, secondFontLoader.isRegistered); +} + - (void)testProvidesACustomFont { // Given MDCFontDiskLoader *resource = [self validResource]; From 25f4d7caec33172ef9aafc1c633c03740da62d16 Mon Sep 17 00:00:00 2001 From: randallli Date: Fri, 3 Jun 2016 13:41:29 -0400 Subject: [PATCH 08/28] [MDCFontDiskLoader]? Deprecated properties that should not have been public write. Summary: lint Reviewers: ajsecord, O1 Material components iOS Reviewed By: ajsecord, O1 Material components iOS Tags: #material_components_ios Differential Revision: http://codereview.cc/D912 --- components/FontDiskLoader/src/MDCFontDiskLoader.h | 8 ++++++-- components/FontDiskLoader/src/MDCFontDiskLoader.m | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.h b/components/FontDiskLoader/src/MDCFontDiskLoader.h index dc31baf307d..7b179f87c25 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.h +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.h @@ -90,18 +90,22 @@ All instances of MDCFontDiskLoader with the same fontURL have the same value of @c isRegistered. */ -@property(nonatomic) BOOL isRegistered; +@property(nonatomic, readonly) BOOL isRegistered; /** This flag is true when the registration failed. It prevents future attempts at registration. To reset call @c unregisterFont. */ -@property(nonatomic) BOOL hasFailedRegistration; +@property(nonatomic, readonly) BOOL hasFailedRegistration; #pragma mark Requesting fonts of a given size /** A convience method for getting a font. */ - (nullable UIFont *)fontOfSize:(CGFloat)fontSize; +// TODO: On or after 6/8/2016 delete these deprecations +- (void)setIsRegistered:(BOOL)isRegistered __deprecated_msg("This setter is no longer public"); +- (void)setHasFailedRegistration:(BOOL)hasFailedRegistration __deprecated_msg("This setter is no longer public"); + @end diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.m b/components/FontDiskLoader/src/MDCFontDiskLoader.m index 273f8390235..8a68e9f0c24 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.m +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.m @@ -20,6 +20,8 @@ @interface MDCFontDiskLoader () @property(nonatomic, strong) NSURL *fontURL; +@property(nonatomic) BOOL isRegistered; +@property(nonatomic) BOOL hasFailedRegistration; @end static NSMutableSet *registeredFonts; @@ -63,16 +65,23 @@ - (BOOL)registerFont { return NO; } CFErrorRef error = NULL; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" self.isRegistered = CTFontManagerRegisterFontsForURL((__bridge CFURLRef)self.fontURL, kCTFontManagerScopeProcess, &error); +#pragma clang diagnostic pop + if (!self.isRegistered) { if (error && CFErrorGetCode(error) == kCTFontManagerErrorAlreadyRegistered) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // If it's already been loaded by somebody else, we don't care. // We do not check the error domain to make sure they match because // kCTFontManagerErrorDomain is not defined in the iOS 8 SDK. // Radar 18651170 iOS 8 SDK missing definition for kCTFontManagerErrorDomain self.isRegistered = YES; +#pragma clang diagnostic pop } else { NSLog(@"Failed to load font: %@", error); _hasFailedRegistration = YES; @@ -90,9 +99,13 @@ - (BOOL)unregisterFont { return YES; } CFErrorRef error = NULL; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" self.isRegistered = !CTFontManagerUnregisterFontsForURL((__bridge CFURLRef)self.fontURL, kCTFontManagerScopeProcess, &error); +#pragma clang diagnostic pop + if (self.isRegistered || error) { NSLog(@"Failed to unregister font: %@", error); } From 265e5147678c5c4b6968878b4ad5e05cbad295dc Mon Sep 17 00:00:00 2001 From: randallli Date: Fri, 3 Jun 2016 11:04:54 -0400 Subject: [PATCH 09/28] [Pesto] Added explicit bundle id Reviewers: ajsecord, O1 Material components iOS Reviewed By: ajsecord, O1 Material components iOS Subscribers: ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D932 --- demos/Pesto/Pesto/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/Pesto/Pesto/Info.plist b/demos/Pesto/Pesto/Info.plist index 862232fff95..6ad3a891b19 100644 --- a/demos/Pesto/Pesto/Info.plist +++ b/demos/Pesto/Pesto/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) + com.google.mdc-pesto CFBundleInfoDictionaryVersion 6.0 CFBundleName From c5198791e59205a14afbedbac2eba3aab8a9f3b9 Mon Sep 17 00:00:00 2001 From: randallli Date: Fri, 3 Jun 2016 11:15:43 -0400 Subject: [PATCH 10/28] [Shrine] Added explicit bundle id Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D933 --- demos/Shrine/Shrine/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/Shrine/Shrine/Info.plist b/demos/Shrine/Shrine/Info.plist index e9241ee9d4f..f007b22f716 100644 --- a/demos/Shrine/Shrine/Info.plist +++ b/demos/Shrine/Shrine/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) + com.google.mdc-shrine CFBundleInfoDictionaryVersion 6.0 CFBundleName From d62b6dc116d8db90e1f1953c48c0e8b6c45949de Mon Sep 17 00:00:00 2001 From: randallli Date: Fri, 3 Jun 2016 13:45:46 -0400 Subject: [PATCH 11/28] [FontDiskLoader]? added warning NSLog when failing to load the font by name. Summary: This is the deprecation warning for breaking change: http://codereview.cc/D911 Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Subscribers: ajsecord, iangordon Tags: #material_components_ios Differential Revision: http://codereview.cc/D923 --- components/FontDiskLoader/src/MDCFontDiskLoader.m | 9 ++++++++- .../FontDiskLoader/tests/unit/FontDiskLoaderTests.m | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/components/FontDiskLoader/src/MDCFontDiskLoader.m b/components/FontDiskLoader/src/MDCFontDiskLoader.m index 8a68e9f0c24..3d170a89166 100644 --- a/components/FontDiskLoader/src/MDCFontDiskLoader.m +++ b/components/FontDiskLoader/src/MDCFontDiskLoader.m @@ -114,7 +114,14 @@ - (BOOL)unregisterFont { - (UIFont *)fontOfSize:(CGFloat)fontSize { [self registerFont]; - return [UIFont fontWithName:self.fontName size:fontSize]; + UIFont *font = [UIFont fontWithName:self.fontName size:fontSize]; +#if DEBUG + if (font == nil) { + NSLog(@"Warning: This log will turn into an NSAssert on or after 6/8/2016"); + NSLog(@"Failed to find font: %@ in file at %@", self.fontName, self.fontURL); + } +#endif + return font; } - (NSString *)description { diff --git a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m index 452f04abe5c..51f5626c946 100644 --- a/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m +++ b/components/FontDiskLoader/tests/unit/FontDiskLoaderTests.m @@ -43,7 +43,7 @@ - (MDCFontDiskLoader *)validResource { - (MDCFontDiskLoader *)invalidResource { NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(MDCRobotoFontLoaderClassname)]; - return [[MDCFontDiskLoader alloc] initWithFontName:MDCRobotoRegularFontName + return [[MDCFontDiskLoader alloc] initWithFontName:@"some invalid font name" filename:@"some invalid filename" bundleFileName:MDCRobotoBundle baseBundle:bundle]; @@ -120,6 +120,7 @@ - (void)testRegisterFontFailure { [resource registerFont]; // Then + XCTAssertNil([resource fontOfSize:10]); XCTAssertTrue(resource.hasFailedRegistration); } From ae21fd0453b3f932e2926a14518009429190c39c Mon Sep 17 00:00:00 2001 From: Louis Romero Date: Fri, 3 Jun 2016 22:38:15 +0200 Subject: [PATCH 12/28] Set an accessibility identifier on the default back button. Summary: The back button created by the AppBar didn't have an accessibility identifier. The accessibility identifier is convenient in UI tests. Test Plan: Check that App Bar back buttons have an accessibility identifier. Reviewers: featherless, randallli, O1 Material components iOS Reviewed By: randallli, O1 Material components iOS Subscribers: randallli Tags: #material_components_ios Differential Revision: http://codereview.cc/D935 --- components/AppBar/src/MDCAppBar.m | 1 + 1 file changed, 1 insertion(+) diff --git a/components/AppBar/src/MDCAppBar.m b/components/AppBar/src/MDCAppBar.m index 496e9218495..e175092a7b3 100644 --- a/components/AppBar/src/MDCAppBar.m +++ b/components/AppBar/src/MDCAppBar.m @@ -169,6 +169,7 @@ - (UIBarButtonItem *)backButtonItem { target:self action:@selector(didTapBackButton:)]; } + backBarButtonItem.accessibilityIdentifier = @"back_back_button"; return backBarButtonItem; } From f5a6ce7244edd1ad67fc8a04a0a087623936db32 Mon Sep 17 00:00:00 2001 From: Louis Romero Date: Fri, 3 Jun 2016 23:12:21 +0200 Subject: [PATCH 13/28] Fix typo in back item accessibility identifier. Reviewers: randallli, O1 Material components iOS Reviewed By: randallli, O1 Material components iOS Tags: #material_components_ios Differential Revision: http://codereview.cc/D937 --- components/AppBar/src/MDCAppBar.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/AppBar/src/MDCAppBar.m b/components/AppBar/src/MDCAppBar.m index e175092a7b3..5dd97e4e557 100644 --- a/components/AppBar/src/MDCAppBar.m +++ b/components/AppBar/src/MDCAppBar.m @@ -169,7 +169,7 @@ - (UIBarButtonItem *)backButtonItem { target:self action:@selector(didTapBackButton:)]; } - backBarButtonItem.accessibilityIdentifier = @"back_back_button"; + backBarButtonItem.accessibilityIdentifier = @"back_bar_button"; return backBarButtonItem; } From d589b27330d717c9d7a4bd1ebea562453f5c5639 Mon Sep 17 00:00:00 2001 From: Junius Gunaratne Date: Mon, 6 Jun 2016 14:00:43 -0400 Subject: [PATCH 14/28] [ActivityIndicator] Adding activity indicator component and demo Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D936 --- MaterialComponents.podspec | 6 + .../examples/ActivityIndicatorExample.m | 190 +++++ .../src/MDCActivityIndicator.h | 131 +++ .../src/MDCActivityIndicator.m | 800 ++++++++++++++++++ .../src/MaterialActivityIndicator.h | 17 + 5 files changed, 1144 insertions(+) create mode 100644 components/ActivityIndicator/examples/ActivityIndicatorExample.m create mode 100644 components/ActivityIndicator/src/MDCActivityIndicator.h create mode 100644 components/ActivityIndicator/src/MDCActivityIndicator.m create mode 100644 components/ActivityIndicator/src/MaterialActivityIndicator.h diff --git a/MaterialComponents.podspec b/MaterialComponents.podspec index 2db94f44f78..d31840de27c 100644 --- a/MaterialComponents.podspec +++ b/MaterialComponents.podspec @@ -38,6 +38,12 @@ Pod::Spec.new do |s| # end # + s.subspec "ActivityIndicator" do |ss| + ss.public_header_files = "components/#{ss.base_name}/src/*.h" + ss.source_files = "components/#{ss.base_name}/src/*.{h,m}", "components/#{ss.base_name}/src/private/*.{h,m}" + ss.header_mappings_dir = "components/#{ss.base_name}/src/*" + end + s.subspec "AppBar" do |ss| ss.public_header_files = "components/#{ss.base_name}/src/*.h" ss.source_files = "components/#{ss.base_name}/src/*.{h,m}" diff --git a/components/ActivityIndicator/examples/ActivityIndicatorExample.m b/components/ActivityIndicator/examples/ActivityIndicatorExample.m new file mode 100644 index 00000000000..08943e92cbe --- /dev/null +++ b/components/ActivityIndicator/examples/ActivityIndicatorExample.m @@ -0,0 +1,190 @@ +/* + 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. + */ + +#import + +#import "MaterialActivityIndicator.h" +#import "MaterialTypography.h" + +static const CGFloat kActivityIndicatorRadius = 72.f; +static const CGFloat kActivityInitialProgress = 0.6f; + +@interface ActivityIndicatorExample : UIViewController + +@property(nonatomic, strong) MDCActivityIndicator *activityIndicator; +@property(nonatomic, strong) UILabel *determinateSwitchLabel; +@property(nonatomic, strong) UILabel *onSwitchLabel; +@property(nonatomic, strong) UILabel *progressLabel; +@property(nonatomic, strong) UILabel *progressPercentLabel; +@property(nonatomic, strong) UISlider *slider; +@property(nonatomic, strong) UISwitch *onSwitch; +@property(nonatomic, strong) UISwitch *determinateSwitch; + +@end + +@implementation ActivityIndicatorExample + +- (id)init { + self = [super init]; + if (self) { + self.title = @"Activity Indicator"; + self.view.backgroundColor = [UIColor whiteColor]; + + CGRect activityIndicator = CGRectMake(0, + 0, + kActivityIndicatorRadius * 2, + kActivityIndicatorRadius * 2); + _activityIndicator = [[MDCActivityIndicator alloc] initWithFrame:activityIndicator]; + _activityIndicator.delegate = self; + _activityIndicator.radius = kActivityIndicatorRadius; + _activityIndicator.strokeWidth = 8.f; + + _activityIndicator.autoresizingMask = + (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | + UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin); + [self.view addSubview:_activityIndicator]; + + _activityIndicator.indicatorMode = MDCActivityIndicatorModeDeterminate; + _activityIndicator.progress = kActivityInitialProgress; + [_activityIndicator startAnimating]; + } + return self; +} + +@end + +@implementation ActivityIndicatorExample (CatalogByConvention) + +- (void)viewDidLoad { + [super viewDidLoad]; + [self setupViews]; +} + +- (void)setupViews { + _onSwitch = [[UISwitch alloc] init]; + [_onSwitch setOn:YES]; + [_onSwitch addTarget:self + action:@selector(didChangeOnSwitch:) + forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:_onSwitch]; + + _onSwitchLabel = [[UILabel alloc] init]; + _onSwitchLabel.text = @"Indicator Active"; + _onSwitchLabel.font = [MDCTypography captionFont]; + _onSwitchLabel.alpha = [MDCTypography captionFontOpacity]; + [_onSwitchLabel sizeToFit]; + [self.view addSubview:_onSwitchLabel]; + + _determinateSwitch = [[UISwitch alloc] init]; + [_determinateSwitch setOn:YES]; + [_determinateSwitch addTarget:self + action:@selector(didChangeDeterminateSwitch:) + forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:_determinateSwitch]; + + _determinateSwitchLabel = [[UILabel alloc] init]; + _determinateSwitchLabel.text = @"Determinate Mode"; + _determinateSwitchLabel.font = [MDCTypography captionFont]; + _determinateSwitchLabel.alpha = [MDCTypography captionFontOpacity]; + [_determinateSwitchLabel sizeToFit]; + [self.view addSubview:_determinateSwitchLabel]; + + CGRect sliderFrame = CGRectMake(0, 0, 240, 27); + _slider = [[UISlider alloc] initWithFrame:sliderFrame]; + _slider.value = kActivityInitialProgress; + [_slider addTarget:self + action:@selector(didChangeSliderValue:) + forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:_slider]; + + _progressLabel = [[UILabel alloc] init]; + _progressLabel.text = @"Progress"; + _progressLabel.font = [MDCTypography captionFont]; + _progressLabel.alpha = [MDCTypography captionFontOpacity]; + [_progressLabel sizeToFit]; + [self.view addSubview:_progressLabel]; + + _progressPercentLabel = [[UILabel alloc] init]; + _progressPercentLabel.text = + [NSString stringWithFormat:@"%.00f%%", kActivityInitialProgress * 100]; + _progressPercentLabel.font = [MDCTypography captionFont]; + _progressPercentLabel.alpha = [MDCTypography captionFontOpacity]; + _progressPercentLabel.frame = CGRectMake(0, 0, 100, 16); + _progressPercentLabel.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:_progressPercentLabel]; +} + +- (void)viewWillLayoutSubviews { + [super viewWillLayoutSubviews]; + CGFloat navHeight = self.navigationController.navigationBar.frame.size.height; + _slider.center = CGPointMake(CGRectGetMidX(self.view.frame), 100); + _progressLabel.center = CGPointMake(CGRectGetMidX(self.view.frame), 130); + _activityIndicator.center = CGPointMake(CGRectGetMidX(self.view.frame), + CGRectGetMidY(self.view.frame) - navHeight * 2); + _progressPercentLabel.center = _activityIndicator.center; + _onSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) - 50, + self.view.frame.size.height - 150); + _determinateSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) - 50, + self.view.frame.size.height - 100); + _onSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 32, + self.view.frame.size.height - 150); + _determinateSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 38, + self.view.frame.size.height - 100); +} + +- (void)didChangeDeterminateSwitch:(UISwitch *)determinateSwitch { + if (determinateSwitch.on) { + _activityIndicator.indicatorMode = MDCActivityIndicatorModeDeterminate; + } else { + _activityIndicator.indicatorMode = MDCActivityIndicatorModeIndeterminate; + } +} + +- (void)didChangeOnSwitch:(UISwitch *)onSwitch { + if (onSwitch.on) { + [_activityIndicator startAnimating]; + } else { + [_activityIndicator stopAnimating]; + } +} + +- (void)didChangeSliderValue:(UISlider *)slider { + _activityIndicator.progress = slider.value; + _progressPercentLabel.text = [NSString stringWithFormat:@"%.00f%%", slider.value * 100]; +} + +#pragma mark - MDCActivityIndicatorDelegate + +- (void)activityIndicatorAnimationDidFinish:(nonnull MDCActivityIndicator *)activityIndicator { + return; +} + +#pragma mark - Catalog by Convention + ++ (NSArray *)catalogBreadcrumbs { + return @[ @"Activity Indicator", @"Activity Indicator" ]; +} + ++ (NSString *)catalogDescription { + return @"Activity Indicator is a visual indication of an app loading content. It can display how " + @"long an operation will take or visualize an unspecified wait time."; +} + ++ (BOOL)catalogIsPrimaryDemo { + return YES; +} + +@end diff --git a/components/ActivityIndicator/src/MDCActivityIndicator.h b/components/ActivityIndicator/src/MDCActivityIndicator.h new file mode 100644 index 00000000000..31760b65ae0 --- /dev/null +++ b/components/ActivityIndicator/src/MDCActivityIndicator.h @@ -0,0 +1,131 @@ +/* + 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. + */ + +#import + +@protocol MDCActivityIndicatorDelegate; + +/** + Different operating modes for the activity indicator. + + This component can be used as a determinate progress indicator or an indeterminate activity + indicator. + + Default value is MDCActivityIndicatorModeIndeterminate. + */ +typedef NS_ENUM(NSInteger, MDCActivityIndicatorMode) { + /** Indeterminate indicators visualize an unspecified wait time. */ + MDCActivityIndicatorModeIndeterminate, + /** Determinate indicators display how long an operation will take. */ + MDCActivityIndicatorModeDeterminate, +}; + +/** + A Material Design activity indicator. + + The activity indicator is a circular spinner that shows progress of an operation. By default the + activity indicator assumes indeterminate progress of an unspecified length of time. In contrast to + a standard UIActivityIndicator, MDCActivityIndicator supports showing determinate progress and uses + custom Material Design animation for indeterminate progress. + + See https://www.google.com/design/spec/components/progress-activity.html + */ +IB_DESIGNABLE +@interface MDCActivityIndicator : UIView + +/** + The callback delegate. See @c MDCActivityIndicatorDelegate. + */ +@property(nonatomic, weak, nullable) id delegate; + +/** + Whether or not the activity indicator is currently animating. + */ +@property(nonatomic, assign, getter=isAnimating) BOOL animating; + +/** + Spinner radius width. Defaults to 12dp (24x24dp circle), constrained to range [8dp, 72dp]. The + spinner is centered in the view's bounds. If the bounds are smaller than the diameter of the + spinner, the spinner may be clipped when clipToBounds is true. + */ +@property(nonatomic, assign) CGFloat radius UI_APPEARANCE_SELECTOR; + +/** + Spinner stroke width. Defaults to 2dp. + */ +@property(nonatomic, assign) CGFloat strokeWidth UI_APPEARANCE_SELECTOR; + +/** + Show a faint ink track along the path of the indicator. Should be enabled when the activity + indicator wraps around another circular element, such as an avatar or a FAB. Defaults to NO. + */ +@property(nonatomic, assign) IBInspectable BOOL trackEnabled; + +/** + The mode of the activity indicator. Default is MDCActivityIndicatorModeIndeterminate. If + currently animating, it will animate the transition between the current mode to the new mode. + */ +@property(nonatomic, assign) IBInspectable MDCActivityIndicatorMode indicatorMode; + +/** + Set the mode of the activity indicator. If currently animating, it will animate the transition + between the current mode to the new mode. Default is MDCActivityIndicatorModeIndeterminate with no + animation. + */ +- (void)setIndicatorMode:(MDCActivityIndicatorMode)mode animated:(BOOL)animated; + +/** + Progress is the extent to which the activity indicator circle is drawn to completion when + indicatorMode is MDCActivityIndicatorModeDeterminate. Progress is drawn clockwise to complete a + circle. Valid range is between [0-1]. Default is zero. 0.5 progress is half the circle. The + transitions between progress levels are animated. + */ +@property(nonatomic, assign) IBInspectable float progress; + +/** + The array of colors that are cycled through when animating the spinner. Populated with default + colors of blue, red, yellow and green on initialization. An empty array results in a blue spinner + with no color cycling. + */ +@property(nonatomic, copy, nonnull) NSArray *cycleColors UI_APPEARANCE_SELECTOR; + +/** + Starts the animated activity indicator. Does nothing if the spinner is already animating. + */ +- (void)startAnimating; + +/** + Stops the animated activity indicator with a short opacity and stroke width animation. Does nothing + if the spinner is not animating. + */ +- (void)stopAnimating; + +@end + +/** + Delegate protocol for the MDCActivityIndicator. + */ +@protocol MDCActivityIndicatorDelegate + +/** + When stop is called, the spinner gracefully animates out using opacity and stroke width. + This method is called after that fade-out animation completes. + + @param activityIndicator Caller + */ +- (void)activityIndicatorAnimationDidFinish:(nonnull MDCActivityIndicator *)activityIndicator; + +@end diff --git a/components/ActivityIndicator/src/MDCActivityIndicator.m b/components/ActivityIndicator/src/MDCActivityIndicator.m new file mode 100644 index 00000000000..d2f15e0065a --- /dev/null +++ b/components/ActivityIndicator/src/MDCActivityIndicator.m @@ -0,0 +1,800 @@ +/* + 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. + */ + +#import "MDCActivityIndicator.h" + +static const NSInteger kMDCActivityIndicatorTotalDetentCount = 5; +static const NSTimeInterval kMDCActivityIndicatorAnimateOutDuration = 0.1f; +static const NSTimeInterval kMDCActivityIndicatorPointCycleDuration = 4.0f / 3.0f; +static const NSTimeInterval kMDCActivityIndicatorPointCycleMinimumVariableDuration = + kMDCActivityIndicatorPointCycleDuration / 8; +static const CGFloat kCycleRotation = 3.0f / 2.0f; +static const CGFloat kOuterRotationIncrement = (1.0f / kMDCActivityIndicatorTotalDetentCount) * + (CGFloat)M_PI; +static const CGFloat kSpinnerRadius = 12.f; +static const CGFloat kStrokeLength = 0.75f; + +/** + Total rotation (outer rotation + stroke rotation) per _cycleCount. One turn is 2.0f. + */ +static const CGFloat kSingleCycleRotation = 2 * kStrokeLength + kCycleRotation + 1.0f / + kMDCActivityIndicatorTotalDetentCount; + +/* + States for the internal state machine. The states represent the last animation completed. + It provides information required to select the next animation. + */ +typedef NS_ENUM(NSInteger, MDCActivityIndicatorState) { + MDCActivityIndicatorStateIndeterminate, + MDCActivityIndicatorStateTransitionToDeterminate, + MDCActivityIndicatorStateDeterminate, + MDCActivityIndicatorStateTransitionToIndeterminate, +}; + +@interface MDCActivityIndicator () + +/** + The minimum stroke difference to use when collapsing the stroke to a dot. Based on current + radius and stroke width. + */ +@property(nonatomic, assign, readonly) CGFloat minStrokeDifference; + +/** + The current color count for the spinner. Subclasses can change this value to start the spinner at + a different color. + */ +@property(nonatomic, assign) NSUInteger currentColorCount; + +/** + The current cycle count. + */ +@property(nonatomic, assign, readonly) NSInteger cycleCount; + +/** + The cycle index at which to start the activity spinner animation. Default is 0, which corresponds + to the top of the spinner (12 o'clock position). Spinner cycle indices are based on a 5-point + star. + */ +@property(nonatomic, assign) NSInteger cycleStartIndex; + +/** + The outer layer that handles cycle rotations and houses the stroke layer. + */ +@property(nonatomic, strong, readonly, nullable) CALayer *outerRotationLayer; + +/** + The shape layer that handles the animating stroke. + */ +@property(nonatomic, strong, readonly, nullable) CAShapeLayer *strokeLayer; + +/** + The shape layer that shows a faint, circular track along the path of the stroke layer. Enabled + via the trackEnabled property. + */ +@property(nonatomic, strong, readonly, nullable) CAShapeLayer *trackLayer; + +@end + +@implementation MDCActivityIndicator { + BOOL _animatingOut; + BOOL _animationsAdded; + BOOL _animationInProgress; + BOOL _backgrounded; + BOOL _cycleInProgress; + CGFloat _currentProgress; + CGFloat _lastProgress; + MDCActivityIndicatorState _lastCompletedState; +} + +#pragma mark - Init + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)coder { + self = [super initWithCoder:coder]; + if (self) { + [self commonInitializer]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + [self applyPropertiesWithoutAnimation:^{ + // Resize and recenter rotation layer. + _outerRotationLayer.bounds = self.bounds; + _outerRotationLayer.position = + CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2); + + _strokeLayer.bounds = _outerRotationLayer.bounds; + _strokeLayer.position = _outerRotationLayer.position; + + [self updateStrokePath]; + }]; +} + +- (void)commonInitializer { + // Register notifications for foreground and background if needed. + [self registerForegroundAndBackgroundNotificationObserversIfNeeded]; + + _cycleStartIndex = 0; + _indicatorMode = MDCActivityIndicatorModeIndeterminate; + + // Property defaults. + _radius = kSpinnerRadius; + _strokeWidth = 2.0f; + + // Colors. + _cycleColors = [MDCActivityIndicator defaultColors]; + _currentColorCount = 0; + + // Track layer. + _trackLayer = [CAShapeLayer layer]; + _trackLayer.lineWidth = _strokeWidth; + _trackLayer.fillColor = [UIColor clearColor].CGColor; + [self.layer addSublayer:_trackLayer]; + _trackLayer.hidden = YES; + + // Rotation layer. + _outerRotationLayer = [CALayer layer]; + [self.layer addSublayer:_outerRotationLayer]; + + // Stroke layer. + _strokeLayer = [CAShapeLayer layer]; + _strokeLayer.lineWidth = _strokeWidth; + _strokeLayer.fillColor = [UIColor clearColor].CGColor; + _strokeLayer.strokeStart = 0; + _strokeLayer.strokeEnd = 0; + [_outerRotationLayer addSublayer:_strokeLayer]; +} + +#pragma mark - UIView + +- (void)willMoveToWindow:(UIWindow *)newWindow { + // If the activity indicator is removed from the window, we should + // immediately stop animating, otherwise it will start chewing up CPU. + if (!newWindow) { + [self actuallyStopAnimating]; + } else if (_animating && !_backgrounded) { + [self actuallyStartAnimating]; + } +} + +#pragma mark - Public methods + +- (void)startAnimating { + if (_animatingOut) { + [self removeAnimations]; + } + + if (_animating) { + return; + } + + _animating = YES; + + if (self.window && !_backgrounded) { + [self actuallyStartAnimating]; + } +} + +- (void)stopAnimating { + if (!_animating) { + return; + } + + _animating = NO; + + [self animateOut]; +} + +- (void)stopAnimatingImmediately { + if (!_animating) { + return; + } + + _animating = NO; + + [self actuallyStopAnimating]; + [_delegate activityIndicatorAnimationDidFinish:self]; +} + +- (void)resetStrokeColor { + _currentColorCount = 0; + + [self updateStrokeColor]; +} + +- (void)setStrokeColor:(UIColor *)strokeColor { + _strokeLayer.strokeColor = strokeColor.CGColor; + _trackLayer.strokeColor = [strokeColor colorWithAlphaComponent:0.3f].CGColor; +} + +- (void)setIndicatorMode:(MDCActivityIndicatorMode)indicatorMode { + if (_indicatorMode == indicatorMode) { + return; + } + _indicatorMode = indicatorMode; + if (_animating && !_animationInProgress) { + switch (indicatorMode) { + case MDCActivityIndicatorModeDeterminate: + [self addTransitionToDeterminateCycle]; + break; + case MDCActivityIndicatorModeIndeterminate: + [self addTransitionToIndeterminateCycle]; + break; + } + } +} + +- (void)setIndicatorMode:(MDCActivityIndicatorMode)mode animated:(BOOL)animated { + [self setIndicatorMode:mode]; +} + +- (void)setProgress:(float)progress { + _progress = MAX(0.0f, MIN(progress, 1.0f)); + if (_progress == _currentProgress) { + return; + } + if (_animating && !_animationInProgress) { + switch (_indicatorMode) { + case MDCActivityIndicatorModeDeterminate: + // Currently animating the determinate mode but no animation queued. + [self addProgressAnimation]; + break; + case MDCActivityIndicatorModeIndeterminate: + break; + } + } +} + +#pragma mark - Properties + +- (void)setStrokeWidth:(CGFloat)strokeWidth { + _strokeWidth = strokeWidth; + _strokeLayer.lineWidth = _strokeWidth; + _trackLayer.lineWidth = _strokeWidth; + + [self updateStrokePath]; +} + +- (void)setSpinnerRadius:(CGFloat)spinnerRadius { + // Constrain radius to range [8dp, 72dp]. + _radius = MIN(MAX(spinnerRadius, 8.0f), 72.0f); + + [self updateStrokePath]; +} + +- (void)setTrackEnabled:(BOOL)trackEnabled { + _trackEnabled = trackEnabled; + + _trackLayer.hidden = !_trackEnabled; +} + +#pragma mark - Private methods + +/** + If this class is not being run in an extension, register for foreground changes and initialize + the app background state in case UI is created when the app is backgrounded. (Extensions always + return UIApplicationStateBackground for |[UIApplication sharedApplication].applicationState|.) + */ +- (void)registerForegroundAndBackgroundNotificationObserversIfNeeded { + if ([[self class] isExtension]) { + return; + } + + _backgrounded = + [UIApplication sharedApplication].applicationState == UIApplicationStateBackground; + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter addObserver:self + selector:@selector(controlAnimatingOnForegroundChange:) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(controlAnimatingOnForegroundChange:) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; +} + +- (void)controlAnimatingOnForegroundChange:(NSNotification *)notification { + // Stop or restart animating if the app has a foreground change. + _backgrounded = + [notification.name isEqualToString:UIApplicationDidEnterBackgroundNotification]; + if (_animating) { + if (_backgrounded) { + [self actuallyStopAnimating]; + } else if (self.window) { + [self actuallyStartAnimating]; + } + } +} + +- (void)actuallyStartAnimating { + if (_animationsAdded) { + return; + } + _animationsAdded = YES; + _cycleCount = _cycleStartIndex; + + [self applyPropertiesWithoutAnimation:^{ + _strokeLayer.strokeStart = 0.0f; + _strokeLayer.strokeEnd = 0.001f; + _strokeLayer.lineWidth = _strokeWidth; + _trackLayer.lineWidth = _strokeWidth; + + [self resetStrokeColor]; + [self updateStrokePath]; + }]; + + switch (_indicatorMode) { + case MDCActivityIndicatorModeIndeterminate: + [self addStrokeRotationCycle]; + break; + case MDCActivityIndicatorModeDeterminate: + [self addProgressAnimation]; + break; + } +} + +- (void)actuallyStopAnimating { + if (!_animationsAdded) { + return; + } + + [self removeAnimations]; + [self applyPropertiesWithoutAnimation:^{ + _strokeLayer.strokeStart = 0.0f; + _strokeLayer.strokeEnd = 0.0f; + }]; +} + +- (void)updateStrokePath { + CGFloat offsetRadius = _radius - _strokeLayer.lineWidth / 2.0f; + UIBezierPath *strokePath = [UIBezierPath bezierPathWithArcCenter:_strokeLayer.position + radius:offsetRadius + startAngle:-1.0f * (CGFloat)M_PI_2 + endAngle:3.0f * (CGFloat)M_PI_2 + clockwise:YES]; + _strokeLayer.path = strokePath.CGPath; + _trackLayer.path = strokePath.CGPath; + + _minStrokeDifference = _strokeLayer.lineWidth / ((CGFloat)M_PI * 2 * _radius); +} + +- (void)updateStrokeColor { + if (_cycleColors.count > 0) { + [self setStrokeColor:_cycleColors[_currentColorCount]]; + } else { + [self setStrokeColor:[MDCActivityIndicator defaultColors][0]]; + } +} + +- (void)addStrokeRotationCycle { + if (_animationInProgress) { + return; + } + + [CATransaction begin]; + { + [CATransaction setCompletionBlock:^{ + _lastCompletedState = MDCActivityIndicatorStateIndeterminate; + [self strokeRotationCycleFinished]; + }]; + + // Outer 5-point star detent rotation. + CABasicAnimation *outerRotationAnimation = + [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + outerRotationAnimation.duration = kMDCActivityIndicatorPointCycleDuration; + outerRotationAnimation.fromValue = @(kOuterRotationIncrement * _cycleCount); + outerRotationAnimation.toValue = @(kOuterRotationIncrement * (_cycleCount + 1)); + outerRotationAnimation.fillMode = kCAFillModeForwards; + outerRotationAnimation.removedOnCompletion = NO; + [_outerRotationLayer addAnimation:outerRotationAnimation forKey:@"transform.rotation.z"]; + + // Stroke rotation. + CGFloat startRotation = _cycleCount * (CGFloat)M_PI; + CGFloat endRotation = startRotation + kCycleRotation * (CGFloat)M_PI; + + CABasicAnimation *strokeRotationAnimation = + [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + strokeRotationAnimation.duration = kMDCActivityIndicatorPointCycleDuration; + strokeRotationAnimation.fromValue = @(startRotation); + strokeRotationAnimation.toValue = @(endRotation); + strokeRotationAnimation.fillMode = kCAFillModeForwards; + strokeRotationAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeRotationAnimation forKey:@"transform.rotation.z"]; + + // Stroke start. + CABasicAnimation *strokeStartPathAnimation = + [CABasicAnimation animationWithKeyPath:@"strokeStart"]; + strokeStartPathAnimation.duration = kMDCActivityIndicatorPointCycleDuration / 2; + // It is always critical to convertTime:fromLayer: for animations, since changes to layer.speed + // on this layer or parent layers will alter the offset of beginTime. + CFTimeInterval currentTime = [_strokeLayer convertTime:CACurrentMediaTime() fromLayer:nil]; + strokeStartPathAnimation.beginTime = currentTime + kMDCActivityIndicatorPointCycleDuration / 2; + strokeStartPathAnimation.fromValue = @(0.0f); + strokeStartPathAnimation.toValue = @(kStrokeLength); + strokeStartPathAnimation.timingFunction = [self materialEaseInOut]; + strokeStartPathAnimation.fillMode = kCAFillModeBoth; + strokeStartPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeStartPathAnimation forKey:@"strokeStart"]; + + // Stroke end. + CABasicAnimation *strokeEndPathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + strokeEndPathAnimation.duration = kMDCActivityIndicatorPointCycleDuration * + ABS(_lastProgress - _currentProgress); + // Ensure the stroke never completely disappears on start by animating from non-zero start and + // to a value slightly larger than the strokeStart's final value. + strokeEndPathAnimation.fromValue = @(_minStrokeDifference); + strokeEndPathAnimation.toValue = @(kStrokeLength + _minStrokeDifference); + strokeEndPathAnimation.timingFunction = [self materialEaseInOut]; + strokeEndPathAnimation.fillMode = kCAFillModeBoth; + strokeEndPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeEndPathAnimation forKey:@"strokeEnd"]; + } + [CATransaction commit]; + + _animationInProgress = YES; +} + +- (void)addTransitionToIndeterminateCycle { + if (_animationInProgress) { + return; + } + // Find the nearest cycle to transition through. + NSInteger nearestCycle = 0; + CGFloat nearestDistance = CGFLOAT_MAX; + const CGFloat normalizedProgress = MAX(_lastProgress - _minStrokeDifference, 0.0f); + for (NSInteger cycle = 0; cycle < kMDCActivityIndicatorTotalDetentCount; cycle++) { + const CGFloat currentRotation = [self normalizedRotationForCycle:cycle]; + if (currentRotation >= normalizedProgress) { + if (nearestDistance >= (currentRotation - normalizedProgress)) { + nearestDistance = currentRotation - normalizedProgress; + nearestCycle = cycle; + } + } + } + + if (nearestCycle == 0 && _lastProgress <= _minStrokeDifference) { + // Special case for 0% progress. + _cycleCount = nearestCycle; + _lastCompletedState = MDCActivityIndicatorStateTransitionToIndeterminate; + [self strokeRotationCycleFinished]; + return; + } + + _cycleCount = nearestCycle; + + CGFloat targetRotation = [self normalizedRotationForCycle:nearestCycle]; + if (targetRotation <= 0.001f) { + targetRotation = 1.0f; + } + CGFloat normalizedDuration = 2 * (targetRotation + _currentProgress) / kSingleCycleRotation * + (CGFloat)kMDCActivityIndicatorPointCycleDuration; + CGFloat strokeEndTravelDistance = targetRotation - _currentProgress + _minStrokeDifference; + CGFloat totalDistance = targetRotation + strokeEndTravelDistance; + CGFloat strokeStartDuration = MAX(normalizedDuration * targetRotation / totalDistance, + (CGFloat)kMDCActivityIndicatorPointCycleMinimumVariableDuration); + CGFloat strokeEndDuration = MAX(normalizedDuration * strokeEndTravelDistance / totalDistance, + (CGFloat)kMDCActivityIndicatorPointCycleMinimumVariableDuration); + + [CATransaction begin]; + { + [CATransaction setCompletionBlock:^{ + _lastCompletedState = MDCActivityIndicatorStateTransitionToIndeterminate; + [self strokeRotationCycleFinished]; + }]; + + // Stroke start. + CABasicAnimation *strokeStartPathAnimation = + [CABasicAnimation animationWithKeyPath:@"strokeStart"]; + strokeStartPathAnimation.duration = strokeStartDuration; + CFTimeInterval currentTime = [_strokeLayer convertTime:CACurrentMediaTime() fromLayer:nil]; + strokeStartPathAnimation.beginTime = currentTime + strokeEndDuration; + strokeStartPathAnimation.fromValue = @(0.0f); + strokeStartPathAnimation.toValue = @(targetRotation); + strokeStartPathAnimation.timingFunction = [self materialEaseInOut]; + ; + strokeStartPathAnimation.fillMode = kCAFillModeBoth; + strokeStartPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeStartPathAnimation forKey:@"strokeStart"]; + + // Stroke end. + CABasicAnimation *strokeEndPathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + strokeEndPathAnimation.duration = strokeEndDuration; + // Ensure the stroke never completely disappears on start by animating from non-zero start and + // to a value slightly larger than the strokeStart's final value. + strokeEndPathAnimation.fromValue = @(_currentProgress); + strokeEndPathAnimation.toValue = @(targetRotation + _minStrokeDifference); + strokeEndPathAnimation.timingFunction = [self materialEaseInOut]; + strokeEndPathAnimation.fillMode = kCAFillModeBoth; + strokeEndPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeEndPathAnimation forKey:@"strokeEnd"]; + } + [CATransaction commit]; + + _animationInProgress = YES; +} + +- (void)addTransitionToDeterminateCycle { + if (_animationInProgress) { + return; + } + if (!_cycleCount) { + // The animation period is complete: no need for transition. + [_strokeLayer removeAllAnimations]; + [_outerRotationLayer removeAllAnimations]; + // Necessary for transition from indeterminate to determinate when cycle == 0. + _currentProgress = 0.0f; + _lastProgress = _currentProgress; + _lastCompletedState = MDCActivityIndicatorStateTransitionToDeterminate; + [self strokeRotationCycleFinished]; + } else { + _currentProgress = MAX(_progress, _minStrokeDifference); + + CGFloat rotationDelta = 1.0f - [self normalizedRotationForCycle:_cycleCount]; + + // Change the duration relative to the distance in order to keep same relative speed. + CGFloat duration = 2.0f * (rotationDelta + _currentProgress) / kSingleCycleRotation * (CGFloat)kMDCActivityIndicatorPointCycleDuration; + + duration = MAX(duration, + (CGFloat)kMDCActivityIndicatorPointCycleMinimumVariableDuration); + [CATransaction begin]; + { + [CATransaction setCompletionBlock:^{ + _lastCompletedState = MDCActivityIndicatorStateTransitionToDeterminate; + [self strokeRotationCycleFinished]; + }]; + + // Outer 5-point star detent rotation. Required for passing from transitionToIndeterminate to + // transitionToDeterminate. + CABasicAnimation *outerRotationAnimation = + [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + outerRotationAnimation.duration = duration; + outerRotationAnimation.fromValue = @(kOuterRotationIncrement * _cycleCount); + outerRotationAnimation.toValue = @(kOuterRotationIncrement * _cycleCount); + outerRotationAnimation.fillMode = kCAFillModeForwards; + outerRotationAnimation.removedOnCompletion = NO; + [_outerRotationLayer addAnimation:outerRotationAnimation forKey:@"transform.rotation.z"]; + + // Stroke rotation. + CGFloat startRotation = _cycleCount * (CGFloat)M_PI; + CGFloat endRotation = startRotation + rotationDelta * 2.0f * (CGFloat)M_PI; + + CABasicAnimation *strokeRotationAnimation = + [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + strokeRotationAnimation.duration = duration; + strokeRotationAnimation.fromValue = @(startRotation); + strokeRotationAnimation.toValue = @(endRotation); + strokeRotationAnimation.fillMode = kCAFillModeForwards; + strokeRotationAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeRotationAnimation forKey:@"transform.rotation.z"]; + + // Stroke start. + CABasicAnimation *strokeStartPathAnimation = + [CABasicAnimation animationWithKeyPath:@"strokeStart"]; + strokeStartPathAnimation.duration = duration; + // It is always critical to convertTime:fromLayer: for animations, since changes to + // layer.speed on this layer or parent layers will alter the offset of beginTime. + CFTimeInterval currentTime = [_strokeLayer convertTime:CACurrentMediaTime() fromLayer:nil]; + strokeStartPathAnimation.beginTime = currentTime; + strokeStartPathAnimation.fromValue = @(0.0f); + strokeStartPathAnimation.toValue = @(0.0f); + strokeStartPathAnimation.timingFunction = [self materialEaseInOut]; + strokeStartPathAnimation.fillMode = kCAFillModeBoth; + strokeStartPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeStartPathAnimation forKey:@"strokeStart"]; + + // Stroke end. + CABasicAnimation *strokeEndPathAnimation = + [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + strokeEndPathAnimation.duration = duration; + // Ensure the stroke never completely disappears on start by animating from non-zero start and + // to a value slightly larger than the strokeStart's final value. + strokeEndPathAnimation.fromValue = @(_minStrokeDifference); + strokeEndPathAnimation.toValue = @(_currentProgress); + strokeEndPathAnimation.timingFunction = [self materialEaseInOut]; + strokeEndPathAnimation.fillMode = kCAFillModeBoth; + strokeEndPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeEndPathAnimation forKey:@"strokeEnd"]; + } + [CATransaction commit]; + + _animationInProgress = YES; + _lastProgress = _currentProgress; + } +} + +- (CAMediaTimingFunction *)materialEaseInOut { + // This curve is slow both at the beginning and end. + // Visualization of curve http://cubic-bezier.com/#.4,0,.2,1 + return [[CAMediaTimingFunction alloc] initWithControlPoints:0.4f:0.0f:0.2f:1.0f]; +} + +- (void)addProgressAnimation { + if (_animationInProgress) { + return; + } + + _currentProgress = MAX(_progress, _minStrokeDifference); + + [CATransaction begin]; + { + [CATransaction setCompletionBlock:^{ + _lastCompletedState = MDCActivityIndicatorStateDeterminate; + [self strokeRotationCycleFinished]; + }]; + + // Stroke end. + CABasicAnimation *strokeEndPathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + strokeEndPathAnimation.duration = kMDCActivityIndicatorPointCycleDuration / 2; + strokeEndPathAnimation.fromValue = @(_lastProgress); + strokeEndPathAnimation.toValue = @(_currentProgress); + strokeEndPathAnimation.timingFunction = [self materialEaseInOut]; + strokeEndPathAnimation.fillMode = kCAFillModeBoth; + strokeEndPathAnimation.removedOnCompletion = NO; + [_strokeLayer addAnimation:strokeEndPathAnimation forKey:@"strokeEnd"]; + } + + [CATransaction commit]; + + _lastProgress = _currentProgress; + _animationInProgress = YES; +} + +- (void)strokeRotationCycleFinished { + _animationInProgress = NO; + + if (!_animationsAdded) { + return; + } + if (_lastCompletedState == MDCActivityIndicatorStateIndeterminate) { + if (_cycleColors.count > 0) { + _currentColorCount = (_currentColorCount + 1) % _cycleColors.count; + [self updateStrokeColor]; + } + _cycleCount = (_cycleCount + 1) % kMDCActivityIndicatorTotalDetentCount; + } + + switch (_indicatorMode) { + case MDCActivityIndicatorModeDeterminate: + switch (_lastCompletedState) { + case MDCActivityIndicatorStateDeterminate: + case MDCActivityIndicatorStateTransitionToDeterminate: + [self addProgressAnimationIfRequired]; + break; + case MDCActivityIndicatorStateIndeterminate: + case MDCActivityIndicatorStateTransitionToIndeterminate: + [self addTransitionToDeterminateCycle]; + break; + } + break; + case MDCActivityIndicatorModeIndeterminate: + switch (_lastCompletedState) { + case MDCActivityIndicatorStateDeterminate: + case MDCActivityIndicatorStateTransitionToDeterminate: + [self addTransitionToIndeterminateCycle]; + break; + case MDCActivityIndicatorStateIndeterminate: + case MDCActivityIndicatorStateTransitionToIndeterminate: + [self addStrokeRotationCycle]; + break; + } + break; + } +} + +- (void)addProgressAnimationIfRequired { + if (_indicatorMode == MDCActivityIndicatorModeDeterminate) { + if (MAX(_progress, _minStrokeDifference) != _currentProgress) { + // The values were changes in the while animating or animation is starting. + [self addProgressAnimation]; + } + } +} + +/** + Rotation that a given cycle has. Represented between 0.0f (cycle has no rotation) and 1.0f. + */ +- (CGFloat)normalizedRotationForCycle:(NSInteger)cycle { + CGFloat cycleRotation = cycle * kSingleCycleRotation / 2.0f; + return cycleRotation - ((NSInteger)cycleRotation); +} + +- (void)animateOut { + _animatingOut = YES; + + [CATransaction begin]; + + [CATransaction setCompletionBlock:^{ + if (_animatingOut) { + [self removeAnimations]; + [_delegate activityIndicatorAnimationDidFinish:self]; + } + }]; + [CATransaction setAnimationDuration:kMDCActivityIndicatorAnimateOutDuration]; + + _strokeLayer.lineWidth = 0; + _trackLayer.lineWidth = 0; + + [CATransaction commit]; +} + +- (void)removeAnimations { + _animationsAdded = NO; + _animatingOut = NO; + [_strokeLayer removeAllAnimations]; + [_outerRotationLayer removeAllAnimations]; + + // Reset cycle count to 0 rather than cycleStart to reflect default starting position (top). + _cycleCount = 0; + // However _animationInProgress represents the CATransaction that hasn't finished, so we leave it + // alone here. +} + +/** Returns whether this class is being executed in an extension or not. */ ++ (BOOL)isExtension { + return [[[NSBundle mainBundle] executablePath] rangeOfString:@".appex/"].location != NSNotFound; +} + ++ (CGFloat)defaultHeight { + return kSpinnerRadius * 2.f; +} + +- (void)applyPropertiesWithoutAnimation:(void (^)(void))setPropBlock { + [CATransaction begin]; + + // Disable implicit CALayer animations + [CATransaction setDisableActions:YES]; + setPropBlock(); + + [CATransaction commit]; +} + ++ (NSArray *)defaultColors { + static NSArray *defaultColors; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + defaultColors = + @[ [[UIColor alloc] initWithRed:0.129f green:0.588f blue:0.953f alpha:1], + [[UIColor alloc] initWithRed:0.957f + green:0.263f + blue:0.212f + alpha:1], + [[UIColor alloc] initWithRed:1.0f + green:0.922f + blue:0.231f + alpha:1], + [[UIColor alloc] initWithRed:0.298f + green:0.686f + blue:0.314f + alpha:1] ]; + }); + return defaultColors; +} + +@end diff --git a/components/ActivityIndicator/src/MaterialActivityIndicator.h b/components/ActivityIndicator/src/MaterialActivityIndicator.h new file mode 100644 index 00000000000..6789a2dd347 --- /dev/null +++ b/components/ActivityIndicator/src/MaterialActivityIndicator.h @@ -0,0 +1,17 @@ +/* + 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. + */ + +#import "MDCActivityIndicator.h" From fa55cdd03099dfb2822e76222e81f631f7e000d0 Mon Sep 17 00:00:00 2001 From: Yiran Mao Date: Mon, 6 Jun 2016 15:25:34 -0400 Subject: [PATCH 15/28] Correct Roboto Font markdown for design specification link. --- components/FontDiskLoader/README.md | 2 -- components/RobotoFontLoader/README.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/components/FontDiskLoader/README.md b/components/FontDiskLoader/README.md index 05e14dc2459..3cd3a45728e 100644 --- a/components/FontDiskLoader/README.md +++ b/components/FontDiskLoader/README.md @@ -13,11 +13,9 @@ Registers a single custom font asset from disk diff --git a/components/RobotoFontLoader/README.md b/components/RobotoFontLoader/README.md index 993242c719f..2ab3b32d4ce 100644 --- a/components/RobotoFontLoader/README.md +++ b/components/RobotoFontLoader/README.md @@ -18,11 +18,9 @@ The Roboto Font Loader lazy loads the Roboto font. From 41bb895dd6852318cece2c41a6edc9ee48d0159d Mon Sep 17 00:00:00 2001 From: Eric Li Date: Mon, 6 Jun 2016 15:16:47 -0400 Subject: [PATCH 16/28] updated podfiles to include activity indicator Summary: update podfiles to include activity indicator Reviewers: featherless, randallli, O1 Material components iOS Reviewed By: randallli, O1 Material components iOS Tags: #material_components_ios Differential Revision: http://codereview.cc/D940 --- catalog/Podfile.lock | 4 +++- demos/Pesto/Podfile.lock | 4 +++- demos/Shrine/Podfile.lock | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/catalog/Podfile.lock b/catalog/Podfile.lock index 7c28423885a..46a1cc7aced 100644 --- a/catalog/Podfile.lock +++ b/catalog/Podfile.lock @@ -1,5 +1,6 @@ PODS: - MaterialComponents (10.0.0): + - MaterialComponents/ActivityIndicator (= 10.0.0) - MaterialComponents/AppBar (= 10.0.0) - MaterialComponents/ButtonBar (= 10.0.0) - MaterialComponents/Buttons (= 10.0.0) @@ -21,6 +22,7 @@ PODS: - MaterialComponents/SpritedAnimationView (= 10.0.0) - MaterialComponents/Switch (= 10.0.0) - MaterialComponents/Typography (= 10.0.0) + - MaterialComponents/ActivityIndicator (10.0.0) - MaterialComponents/AppBar (10.0.0): - MaterialComponents/FlexibleHeader - MaterialComponents/HeaderStackView @@ -127,7 +129,7 @@ EXTERNAL SOURCES: :path: ../ SPEC CHECKSUMS: - MaterialComponents: c368e132f1750211ec982d3b4c844d2886a785e0 + MaterialComponents: 9c573b7371abd74208fe05a1915f3f02f513a009 MaterialComponentsCatalog: c665fdd39bff9621608cec8fe0a99e44ce8e7a13 MaterialComponentsUnitTests: 66c55d81bb08daf37915f7142244bfeaa04a4776 diff --git a/demos/Pesto/Podfile.lock b/demos/Pesto/Podfile.lock index 146f5aa796b..610df1d31c7 100644 --- a/demos/Pesto/Podfile.lock +++ b/demos/Pesto/Podfile.lock @@ -1,5 +1,6 @@ PODS: - MaterialComponents (10.0.0): + - MaterialComponents/ActivityIndicator (= 10.0.0) - MaterialComponents/AppBar (= 10.0.0) - MaterialComponents/ButtonBar (= 10.0.0) - MaterialComponents/Buttons (= 10.0.0) @@ -21,6 +22,7 @@ PODS: - MaterialComponents/SpritedAnimationView (= 10.0.0) - MaterialComponents/Switch (= 10.0.0) - MaterialComponents/Typography (= 10.0.0) + - MaterialComponents/ActivityIndicator (10.0.0) - MaterialComponents/AppBar (10.0.0): - MaterialComponents/FlexibleHeader - MaterialComponents/HeaderStackView @@ -117,7 +119,7 @@ EXTERNAL SOURCES: :path: ../../ SPEC CHECKSUMS: - MaterialComponents: c368e132f1750211ec982d3b4c844d2886a785e0 + MaterialComponents: 9c573b7371abd74208fe05a1915f3f02f513a009 PODFILE CHECKSUM: f138be16d4835113ff672258fc7529fad3f90e91 diff --git a/demos/Shrine/Podfile.lock b/demos/Shrine/Podfile.lock index 66768e7a6d7..fa40a3e7fe8 100644 --- a/demos/Shrine/Podfile.lock +++ b/demos/Shrine/Podfile.lock @@ -1,5 +1,6 @@ PODS: - MaterialComponents (10.0.0): + - MaterialComponents/ActivityIndicator (= 10.0.0) - MaterialComponents/AppBar (= 10.0.0) - MaterialComponents/ButtonBar (= 10.0.0) - MaterialComponents/Buttons (= 10.0.0) @@ -21,6 +22,7 @@ PODS: - MaterialComponents/SpritedAnimationView (= 10.0.0) - MaterialComponents/Switch (= 10.0.0) - MaterialComponents/Typography (= 10.0.0) + - MaterialComponents/ActivityIndicator (10.0.0) - MaterialComponents/AppBar (10.0.0): - MaterialComponents/FlexibleHeader - MaterialComponents/HeaderStackView @@ -117,7 +119,7 @@ EXTERNAL SOURCES: :path: ../../ SPEC CHECKSUMS: - MaterialComponents: c368e132f1750211ec982d3b4c844d2886a785e0 + MaterialComponents: 9c573b7371abd74208fe05a1915f3f02f513a009 PODFILE CHECKSUM: b585ca32a2884e050823cc1f861e8b7246f7dcc1 From 25ea19e76a7b4d7baf9420639972127022c27602 Mon Sep 17 00:00:00 2001 From: Eric Li Date: Mon, 6 Jun 2016 14:55:56 -0400 Subject: [PATCH 17/28] updated examples and readme to use new swift selector syntax Summary: Updated project to use new swift #selector syntax Closes https://github.com/google/material-components-ios/issues/520. Reviewers: featherless, O1 Material components iOS Reviewed By: featherless, O1 Material components iOS Subscribers: featherless Tags: #material_components_ios Differential Revision: http://codereview.cc/D938 --- README.md | 2 +- .../ButtonBar/examples/ButtonBarTypicalUseExample.swift | 4 ++-- .../examples/ButtonsSimpleExampleSwiftViewController.swift | 6 +++--- .../Buttons/examples/ButtonsStoryboardAndProgrammatic.swift | 6 +++--- .../PageControl/examples/PageControlTypicalUseExample.swift | 2 +- .../examples/ShadowDragSquareExampleViewController.swift | 2 +- .../Switch/examples/SwitchSwiftExampleViewController.swift | 2 +- demos/Shrine/Shrine/ShrineDetailViewController.swift | 2 +- demos/Shrine/Shrine/ShrineHeaderContentView.swift | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 81390ca13c0..6d9d274ab80 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ class MDCBuildTestViewController: UIViewController { let raiseButton = MDCRaisedButton.init(); raiseButton.setTitle("Raised Button", forState: .Normal); raiseButton.sizeToFit(); - raiseButton.addTarget(self, action: "tapped:", forControlEvents: .TouchUpInside); + raiseButton.addTarget(self, action: #selector(tapped), forControlEvents: .TouchUpInside); self.view.addSubview(raiseButton); } diff --git a/components/ButtonBar/examples/ButtonBarTypicalUseExample.swift b/components/ButtonBar/examples/ButtonBarTypicalUseExample.swift index d9a050d537a..3507cc33fbb 100644 --- a/components/ButtonBar/examples/ButtonBarTypicalUseExample.swift +++ b/components/ButtonBar/examples/ButtonBarTypicalUseExample.swift @@ -32,14 +32,14 @@ class ButtonBarTypicalUseSwiftExample: UIViewController { title: "Action", style: ignored, target: self, - action: "didTapActionButton:" + action: #selector(didTapActionButton) ) let secondActionItem = UIBarButtonItem( title: "Second action", style: ignored, target: self, - action: "didTapActionButton:" + action: #selector(didTapActionButton) ) let items = [actionItem, secondActionItem] diff --git a/components/Buttons/examples/ButtonsSimpleExampleSwiftViewController.swift b/components/Buttons/examples/ButtonsSimpleExampleSwiftViewController.swift index c048647f06b..47e3b1f99d1 100644 --- a/components/Buttons/examples/ButtonsSimpleExampleSwiftViewController.swift +++ b/components/Buttons/examples/ButtonsSimpleExampleSwiftViewController.swift @@ -29,7 +29,7 @@ class ButtonsSimpleExampleSwiftViewController: UIViewController { raisedButton.setTitle("Tap Me Too", forState: .Normal) raisedButton.sizeToFit() raisedButton.translatesAutoresizingMaskIntoConstraints = false - raisedButton.addTarget(self, action: "tap:", forControlEvents: .TouchUpInside) + raisedButton.addTarget(self, action: #selector(tap), forControlEvents: .TouchUpInside) self.view.addSubview(raisedButton) let flatButton = MDCFlatButton() @@ -37,14 +37,14 @@ class ButtonsSimpleExampleSwiftViewController: UIViewController { flatButton.setTitle("Touch me", forState: .Normal) flatButton.sizeToFit() flatButton.translatesAutoresizingMaskIntoConstraints = false - flatButton.addTarget(self, action: "tap:", forControlEvents: .TouchUpInside) + flatButton.addTarget(self, action: #selector(tap), forControlEvents: .TouchUpInside) self.view.addSubview(flatButton) let floatingButton = MDCFloatingButton() floatingButton.setTitle("+", forState: .Normal) floatingButton.sizeToFit() floatingButton.translatesAutoresizingMaskIntoConstraints = false - floatingButton.addTarget(self, action: "tap:", forControlEvents: .TouchUpInside) + floatingButton.addTarget(self, action: #selector(tap), forControlEvents: .TouchUpInside) self.view.addSubview(floatingButton) let views = [ diff --git a/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift b/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift index d0fbe341cf3..3504eacb7d6 100644 --- a/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift +++ b/components/Buttons/examples/ButtonsStoryboardAndProgrammatic.swift @@ -49,20 +49,20 @@ class ButtonsStoryboardAndProgrammaticController: UIViewController { raisedButton.setTitle("Programmatic", forState: .Normal) raisedButton.sizeToFit() raisedButton.translatesAutoresizingMaskIntoConstraints = false - raisedButton.addTarget(self, action: "tap:", forControlEvents: .TouchUpInside) + raisedButton.addTarget(self, action: #selector(tap), forControlEvents: .TouchUpInside) self.view.addSubview(raisedButton) flatButton.customTitleColor = UIColor.grayColor() flatButton.setTitle("Programmatic", forState: .Normal) flatButton.sizeToFit() flatButton.translatesAutoresizingMaskIntoConstraints = false - flatButton.addTarget(self, action: "tap:", forControlEvents: .TouchUpInside) + flatButton.addTarget(self, action: #selector(tap), forControlEvents: .TouchUpInside) self.view.addSubview(flatButton) floatingButton.setTitle("+", forState: .Normal) floatingButton.sizeToFit() floatingButton.translatesAutoresizingMaskIntoConstraints = false - floatingButton.addTarget(self, action: "tap:", forControlEvents: .TouchUpInside) + floatingButton.addTarget(self, action: #selector(tap), forControlEvents: .TouchUpInside) self.view.addSubview(floatingButton) let views = [ diff --git a/components/PageControl/examples/PageControlTypicalUseExample.swift b/components/PageControl/examples/PageControlTypicalUseExample.swift index 1a20da3b503..0d4dbd6267b 100644 --- a/components/PageControl/examples/PageControlTypicalUseExample.swift +++ b/components/PageControl/examples/PageControlTypicalUseExample.swift @@ -63,7 +63,7 @@ class PageControlSwiftExampleViewController: UIViewController, UIScrollViewDeleg let pageControlSize = pageControl.sizeThatFits(view.bounds.size) pageControl.frame = CGRectMake(0, view.bounds.height - pageControlSize.height, view.bounds.width, pageControlSize.height); - pageControl.addTarget(self, action: "didChangePage:", forControlEvents: .ValueChanged) + pageControl.addTarget(self, action: #selector(didChangePage), forControlEvents: .ValueChanged) pageControl.autoresizingMask = [.FlexibleTopMargin, .FlexibleWidth]; view.addSubview(pageControl) } diff --git a/components/ShadowLayer/examples/ShadowDragSquareExampleViewController.swift b/components/ShadowLayer/examples/ShadowDragSquareExampleViewController.swift index 6461d2a42b8..fda804d2679 100644 --- a/components/ShadowLayer/examples/ShadowDragSquareExampleViewController.swift +++ b/components/ShadowLayer/examples/ShadowDragSquareExampleViewController.swift @@ -43,7 +43,7 @@ class ShadowDragSquareExampleViewController: UIViewController { self.blueView.setElevation(kRestingCardElevation) - longPressRecogniser.addTarget(self, action: "longPressedInView:") + longPressRecogniser.addTarget(self, action: #selector(longPressedInView)) longPressRecogniser.minimumPressDuration = 0.0 self.blueView.addGestureRecognizer(longPressRecogniser) } diff --git a/components/Switch/examples/SwitchSwiftExampleViewController.swift b/components/Switch/examples/SwitchSwiftExampleViewController.swift index e3b8fc8f258..bc53165a39e 100644 --- a/components/Switch/examples/SwitchSwiftExampleViewController.swift +++ b/components/Switch/examples/SwitchSwiftExampleViewController.swift @@ -27,7 +27,7 @@ class SwitchSwiftExampleViewController : UIViewController { view.backgroundColor = UIColor.whiteColor() switchComponent.on = true - switchComponent.addTarget(self, action: Selector("didChangeSwitchValue:"), forControlEvents: UIControlEvents.ValueChanged) + switchComponent.addTarget(self, action: #selector(didChangeSwitchValue), forControlEvents: UIControlEvents.ValueChanged) view.addSubview(switchComponent) switchComponent.center = CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds)); switchComponent.autoresizingMask = [.FlexibleBottomMargin, .FlexibleTopMargin, .FlexibleLeftMargin, .FlexibleRightMargin] diff --git a/demos/Shrine/Shrine/ShrineDetailViewController.swift b/demos/Shrine/Shrine/ShrineDetailViewController.swift index 11a63462da5..dec14b28627 100644 --- a/demos/Shrine/Shrine/ShrineDetailViewController.swift +++ b/demos/Shrine/Shrine/ShrineDetailViewController.swift @@ -114,7 +114,7 @@ class ShrineDetailViewController: UIViewController { dismissBtn.customTitleColor = UIColor.grayColor() dismissBtn.sizeToFit() dismissBtn.frame = CGRectMake(8, 28, dismissBtn.frame.width, dismissBtn.frame.height) - dismissBtn.addTarget(self, action: "dismissDetails", + dismissBtn.addTarget(self, action: #selector(dismissDetails), forControlEvents: .TouchUpInside) self.view.addSubview(dismissBtn) } diff --git a/demos/Shrine/Shrine/ShrineHeaderContentView.swift b/demos/Shrine/Shrine/ShrineHeaderContentView.swift index 2391994bbe1..4a1386a6458 100644 --- a/demos/Shrine/Shrine/ShrineHeaderContentView.swift +++ b/demos/Shrine/Shrine/ShrineHeaderContentView.swift @@ -74,7 +74,7 @@ class ShrineHeaderContentView: UIView, UIScrollViewDelegate { boundsHeight - pageControlSize.height, boundsWidth, pageControlSize.height) - pageControl.addTarget(self, action: "didChangePage:", + pageControl.addTarget(self, action: #selector(didChangePage), forControlEvents: UIControlEvents.ValueChanged) self.addSubview(pageControl) From c60de65ffdef1cf83d664e429615b87238f15ccf Mon Sep 17 00:00:00 2001 From: Louis Romero Date: Tue, 7 Jun 2016 02:17:50 +0200 Subject: [PATCH 18/28] [AppBar] Respect the navigation bar's layout direction Summary: The back button now faces to the right direction based on the navigation bar's layout direction. Closes https://github.com/google/material-components-ios/issues/564. Test Plan: Open MDCCatalog with Pseudo RTL or an RTL language. Go to a component page. Check that the back button points to the right. Reviewers: iangordon, O1 Material components iOS, featherless Reviewed By: O1 Material components iOS, featherless Tags: #material_components_ios Differential Revision: http://codereview.cc/D942 --- components/AppBar/src/MDCAppBar.m | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/AppBar/src/MDCAppBar.m b/components/AppBar/src/MDCAppBar.m index 5dd97e4e557..9cedfa90022 100644 --- a/components/AppBar/src/MDCAppBar.m +++ b/components/AppBar/src/MDCAppBar.m @@ -164,6 +164,18 @@ - (UIBarButtonItem *)backButtonItem { if (!backBarButtonItem) { UIImage *backButtonImage = [UIImage imageWithContentsOfFile:[MDCIcons pathFor_ic_arrow_back]]; backButtonImage = [backButtonImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + if (self.navigationBar.layoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) { +#if defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 + if ([backButtonImage + respondsToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)]) { + backButtonImage = [backButtonImage imageFlippedForRightToLeftLayoutDirection]; + } +#else + backButtonImage = [UIImage imageWithCGImage:backButtonImage.CGImage + scale:backButtonImage.scale + orientation:UIImageOrientationUpMirrored]; +#endif + } backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:backButtonImage style:UIBarButtonItemStyleDone target:self From 06acbe8cb8b9aa0befea566233f5e7b7528dd8dd Mon Sep 17 00:00:00 2001 From: Junius Gunaratne Date: Tue, 7 Jun 2016 10:53:10 -0400 Subject: [PATCH 19/28] [ActivityIndicator] Move layout code into supplemental, support landscape mode Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D939 --- .../examples/ActivityIndicatorExample.m | 126 +--------------- .../ActivityIndicatorExampleSupplemental.h | 33 +++++ .../ActivityIndicatorExampleSupplemental.m | 139 ++++++++++++++++++ 3 files changed, 175 insertions(+), 123 deletions(-) create mode 100644 components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.h create mode 100644 components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.m diff --git a/components/ActivityIndicator/examples/ActivityIndicatorExample.m b/components/ActivityIndicator/examples/ActivityIndicatorExample.m index 08943e92cbe..6a542c322e2 100644 --- a/components/ActivityIndicator/examples/ActivityIndicatorExample.m +++ b/components/ActivityIndicator/examples/ActivityIndicatorExample.m @@ -16,22 +16,10 @@ #import +#import "ActivityIndicatorExampleSupplemental.h" #import "MaterialActivityIndicator.h" -#import "MaterialTypography.h" -static const CGFloat kActivityIndicatorRadius = 72.f; -static const CGFloat kActivityInitialProgress = 0.6f; - -@interface ActivityIndicatorExample : UIViewController - -@property(nonatomic, strong) MDCActivityIndicator *activityIndicator; -@property(nonatomic, strong) UILabel *determinateSwitchLabel; -@property(nonatomic, strong) UILabel *onSwitchLabel; -@property(nonatomic, strong) UILabel *progressLabel; -@property(nonatomic, strong) UILabel *progressPercentLabel; -@property(nonatomic, strong) UISlider *slider; -@property(nonatomic, strong) UISwitch *onSwitch; -@property(nonatomic, strong) UISwitch *determinateSwitch; +@interface ActivityIndicatorExample () @end @@ -70,100 +58,7 @@ @implementation ActivityIndicatorExample (CatalogByConvention) - (void)viewDidLoad { [super viewDidLoad]; - [self setupViews]; -} - -- (void)setupViews { - _onSwitch = [[UISwitch alloc] init]; - [_onSwitch setOn:YES]; - [_onSwitch addTarget:self - action:@selector(didChangeOnSwitch:) - forControlEvents:UIControlEventValueChanged]; - [self.view addSubview:_onSwitch]; - - _onSwitchLabel = [[UILabel alloc] init]; - _onSwitchLabel.text = @"Indicator Active"; - _onSwitchLabel.font = [MDCTypography captionFont]; - _onSwitchLabel.alpha = [MDCTypography captionFontOpacity]; - [_onSwitchLabel sizeToFit]; - [self.view addSubview:_onSwitchLabel]; - - _determinateSwitch = [[UISwitch alloc] init]; - [_determinateSwitch setOn:YES]; - [_determinateSwitch addTarget:self - action:@selector(didChangeDeterminateSwitch:) - forControlEvents:UIControlEventValueChanged]; - [self.view addSubview:_determinateSwitch]; - - _determinateSwitchLabel = [[UILabel alloc] init]; - _determinateSwitchLabel.text = @"Determinate Mode"; - _determinateSwitchLabel.font = [MDCTypography captionFont]; - _determinateSwitchLabel.alpha = [MDCTypography captionFontOpacity]; - [_determinateSwitchLabel sizeToFit]; - [self.view addSubview:_determinateSwitchLabel]; - - CGRect sliderFrame = CGRectMake(0, 0, 240, 27); - _slider = [[UISlider alloc] initWithFrame:sliderFrame]; - _slider.value = kActivityInitialProgress; - [_slider addTarget:self - action:@selector(didChangeSliderValue:) - forControlEvents:UIControlEventValueChanged]; - [self.view addSubview:_slider]; - - _progressLabel = [[UILabel alloc] init]; - _progressLabel.text = @"Progress"; - _progressLabel.font = [MDCTypography captionFont]; - _progressLabel.alpha = [MDCTypography captionFontOpacity]; - [_progressLabel sizeToFit]; - [self.view addSubview:_progressLabel]; - - _progressPercentLabel = [[UILabel alloc] init]; - _progressPercentLabel.text = - [NSString stringWithFormat:@"%.00f%%", kActivityInitialProgress * 100]; - _progressPercentLabel.font = [MDCTypography captionFont]; - _progressPercentLabel.alpha = [MDCTypography captionFontOpacity]; - _progressPercentLabel.frame = CGRectMake(0, 0, 100, 16); - _progressPercentLabel.textAlignment = NSTextAlignmentCenter; - [self.view addSubview:_progressPercentLabel]; -} - -- (void)viewWillLayoutSubviews { - [super viewWillLayoutSubviews]; - CGFloat navHeight = self.navigationController.navigationBar.frame.size.height; - _slider.center = CGPointMake(CGRectGetMidX(self.view.frame), 100); - _progressLabel.center = CGPointMake(CGRectGetMidX(self.view.frame), 130); - _activityIndicator.center = CGPointMake(CGRectGetMidX(self.view.frame), - CGRectGetMidY(self.view.frame) - navHeight * 2); - _progressPercentLabel.center = _activityIndicator.center; - _onSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) - 50, - self.view.frame.size.height - 150); - _determinateSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) - 50, - self.view.frame.size.height - 100); - _onSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 32, - self.view.frame.size.height - 150); - _determinateSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 38, - self.view.frame.size.height - 100); -} - -- (void)didChangeDeterminateSwitch:(UISwitch *)determinateSwitch { - if (determinateSwitch.on) { - _activityIndicator.indicatorMode = MDCActivityIndicatorModeDeterminate; - } else { - _activityIndicator.indicatorMode = MDCActivityIndicatorModeIndeterminate; - } -} - -- (void)didChangeOnSwitch:(UISwitch *)onSwitch { - if (onSwitch.on) { - [_activityIndicator startAnimating]; - } else { - [_activityIndicator stopAnimating]; - } -} - -- (void)didChangeSliderValue:(UISlider *)slider { - _activityIndicator.progress = slider.value; - _progressPercentLabel.text = [NSString stringWithFormat:@"%.00f%%", slider.value * 100]; + [self setupExampleViews]; } #pragma mark - MDCActivityIndicatorDelegate @@ -172,19 +67,4 @@ - (void)activityIndicatorAnimationDidFinish:(nonnull MDCActivityIndicator *)acti return; } -#pragma mark - Catalog by Convention - -+ (NSArray *)catalogBreadcrumbs { - return @[ @"Activity Indicator", @"Activity Indicator" ]; -} - -+ (NSString *)catalogDescription { - return @"Activity Indicator is a visual indication of an app loading content. It can display how " - @"long an operation will take or visualize an unspecified wait time."; -} - -+ (BOOL)catalogIsPrimaryDemo { - return YES; -} - @end diff --git a/components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.h b/components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.h new file mode 100644 index 00000000000..b0d2762dc28 --- /dev/null +++ b/components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.h @@ -0,0 +1,33 @@ +/* IMPORTANT: + This file contains supplemental code used to populate the demos with dummy data or instructions. + It is not necessary to import this file to implement any Material Design Components. + */ + +#import + +#import "MaterialActivityIndicator.h" + +static const CGFloat kActivityIndicatorRadius = 72.f; +static const CGFloat kActivityInitialProgress = 0.6f; + +@class ActivityIndicatorExample; +@class MDCActivityIndicator; + +@interface ActivityIndicatorExample : UIViewController + +@property(nonatomic, strong) MDCActivityIndicator *activityIndicator; +@property(nonatomic, strong) UILabel *determinateSwitchLabel; +@property(nonatomic, strong) UILabel *onSwitchLabel; +@property(nonatomic, strong) UILabel *progressLabel; +@property(nonatomic, strong) UILabel *progressPercentLabel; +@property(nonatomic, strong) UISlider *slider; +@property(nonatomic, strong) UISwitch *onSwitch; +@property(nonatomic, strong) UISwitch *determinateSwitch; + +@end + +@interface ActivityIndicatorExample (Supplemental) + +- (void)setupExampleViews; + +@end diff --git a/components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.m b/components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.m new file mode 100644 index 00000000000..f65392ee5d5 --- /dev/null +++ b/components/ActivityIndicator/examples/supplemental/ActivityIndicatorExampleSupplemental.m @@ -0,0 +1,139 @@ +/* IMPORTANT: + This file contains supplemental code used to populate the examples with dummy data and/or + instructions. It is not necessary to import this file to implement any Material Design Components. + */ + +#import + +#import "ActivityIndicatorExampleSupplemental.h" +#import "MaterialTypography.h" + +@implementation ActivityIndicatorExample (CatalogByConvention) + ++ (NSArray *)catalogBreadcrumbs { + return @[ @"Activity Indicator", @"Activity Indicator" ]; +} + ++ (NSString *)catalogDescription { + return @"Activity Indicator is a visual indication of an app loading content. It can display how " + @"long an operation will take or visualize an unspecified wait time."; +} + ++ (BOOL)catalogIsPrimaryDemo { + return YES; +} + +@end + +@implementation ActivityIndicatorExample (Supplemental) + +- (void)setupExampleViews { + self.onSwitch = [[UISwitch alloc] init]; + [self.onSwitch setOn:YES]; + [self.onSwitch addTarget:self + action:@selector(didChangeOnSwitch:) + forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:self.onSwitch]; + + self.onSwitchLabel = [[UILabel alloc] init]; + self.onSwitchLabel.text = @"Indicator Active"; + self.onSwitchLabel.font = [MDCTypography captionFont]; + self.onSwitchLabel.alpha = [MDCTypography captionFontOpacity]; + [self.onSwitchLabel sizeToFit]; + [self.view addSubview:self.onSwitchLabel]; + + self.determinateSwitch = [[UISwitch alloc] init]; + [self.determinateSwitch setOn:YES]; + [self.determinateSwitch addTarget:self + action:@selector(didChangeDeterminateSwitch:) + forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:self.determinateSwitch]; + + self.determinateSwitchLabel = [[UILabel alloc] init]; + self.determinateSwitchLabel.text = @"Determinate Mode"; + self.determinateSwitchLabel.font = [MDCTypography captionFont]; + self.determinateSwitchLabel.alpha = [MDCTypography captionFontOpacity]; + [self.determinateSwitchLabel sizeToFit]; + [self.view addSubview:self.determinateSwitchLabel]; + + CGRect sliderFrame = CGRectMake(0, 0, 240, 27); + self.slider = [[UISlider alloc] initWithFrame:sliderFrame]; + self.slider.value = kActivityInitialProgress; + [self.slider addTarget:self + action:@selector(didChangeSliderValue:) + forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:self.slider]; + + self.progressLabel = [[UILabel alloc] init]; + self.progressLabel.text = @"Progress"; + self.progressLabel.font = [MDCTypography captionFont]; + self.progressLabel.alpha = [MDCTypography captionFontOpacity]; + [self.progressLabel sizeToFit]; + [self.view addSubview:self.progressLabel]; + + self.progressPercentLabel = [[UILabel alloc] init]; + self.progressPercentLabel.text = + [NSString stringWithFormat:@"%.00f%%", kActivityInitialProgress * 100]; + self.progressPercentLabel.font = [MDCTypography captionFont]; + self.progressPercentLabel.alpha = [MDCTypography captionFontOpacity]; + self.progressPercentLabel.frame = CGRectMake(0, 0, 100, 16); + self.progressPercentLabel.textAlignment = NSTextAlignmentCenter; + [self.view addSubview:self.progressPercentLabel]; +} + +- (void)viewWillLayoutSubviews { + [super viewWillLayoutSubviews]; + + CGFloat navHeight = self.navigationController.navigationBar.frame.size.height; + if (self.view.frame.size.height > self.view.frame.size.width) { + self.activityIndicator.center = CGPointMake(CGRectGetMidX(self.view.frame), + CGRectGetMidY(self.view.frame) - navHeight * 2); + self.slider.center = CGPointMake(CGRectGetMidX(self.view.frame), 80); + self.progressLabel.center = CGPointMake(CGRectGetMidX(self.view.frame), 110); + self.onSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) - 50, + self.view.frame.size.height - 140); + self.onSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 32, + self.view.frame.size.height - 140); + self.determinateSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) - 50, + self.view.frame.size.height - 90); + self.determinateSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 38, + self.view.frame.size.height - 90); + } else { + self.activityIndicator.center = CGPointMake(CGRectGetMidX(self.view.frame) - 150, + CGRectGetMidY(self.view.frame) - 100); + self.slider.center = CGPointMake(CGRectGetMidX(self.view.frame) + 150, 20); + self.progressLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 150, 50); + self.onSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) + 90, + self.view.frame.size.height - 140); + self.onSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 172, + self.view.frame.size.height - 140); + self.determinateSwitch.center = CGPointMake(CGRectGetMidX(self.view.frame) + 90, + self.view.frame.size.height - 90); + self.determinateSwitchLabel.center = CGPointMake(CGRectGetMidX(self.view.frame) + 178, + self.view.frame.size.height - 90); + } + self.progressPercentLabel.center = self.activityIndicator.center; +} + +- (void)didChangeDeterminateSwitch:(UISwitch *)determinateSwitch { + if (determinateSwitch.on) { + self.activityIndicator.indicatorMode = MDCActivityIndicatorModeDeterminate; + } else { + self.activityIndicator.indicatorMode = MDCActivityIndicatorModeIndeterminate; + } +} + +- (void)didChangeOnSwitch:(UISwitch *)onSwitch { + if (onSwitch.on) { + [self.activityIndicator startAnimating]; + } else { + [self.activityIndicator stopAnimating]; + } +} + +- (void)didChangeSliderValue:(UISlider *)slider { + self.activityIndicator.progress = slider.value; + self.progressPercentLabel.text = [NSString stringWithFormat:@"%.00f%%", slider.value * 100]; +} + +@end From 8355c529da28f10d35fd4643499e7e75740e1919 Mon Sep 17 00:00:00 2001 From: Max Luzuriaga Date: Tue, 7 Jun 2016 12:34:28 -0400 Subject: [PATCH 20/28] [Slider] Fix disabled slider drawing incorrectly at extremes Summary: Resolves #535 by altering the way MDCThumbTrack draws inset tracks. Previously an inset track would span the whole width of the slider, and the bits on the right and left would be masked off. Now the track is set up to only span the necessary width, taking into account the inset without having to mask. This fixes the referenced issue because the same mask to provide the inset effect was also being used to provide the gap to the left and right of the thumb view when the slider was disabled, and the two rects in the mask were interacting in unexpected ways. --- Closes https://github.com/google/material-components-ios/pull/562 GitHub author: maxluzuriaga !![[https://github.com/google/material-components-ios/pull/562 | This is a child of GitHub pull request #562]]!!. Reviewers: github-bot, randallli, #mdc_ios_owners, O1 Material components iOS Reviewed By: randallli, #mdc_ios_owners, O1 Material components iOS Subscribers: mluzuria, randallli Tags: #material_components_ios Differential Revision: http://codereview.cc/D941 --- .../private/ThumbTrack/src/MDCThumbTrack.m | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/components/private/ThumbTrack/src/MDCThumbTrack.m b/components/private/ThumbTrack/src/MDCThumbTrack.m index dbf5932a993..8ddbb7a2d33 100644 --- a/components/private/ThumbTrack/src/MDCThumbTrack.m +++ b/components/private/ThumbTrack/src/MDCThumbTrack.m @@ -437,7 +437,11 @@ - (void)updateColorsAnimated:(BOOL)animated withDuration:(NSTimeInterval)duratio _trackOnLayer.backgroundColor = _trackOnColor.CGColor; CGFloat anchor = [self thumbPositionForValue:_filledTrackAnchorValue].x; - if (!_trackEndsAreInset) { + + if (_trackEndsAreInset) { + // Account for the fact that _trackView is actually shorter in this case + anchor -= _thumbRadius; + } else { if (_filledTrackAnchorValue <= _minimumValue) { anchor -= _thumbRadius; } @@ -470,17 +474,21 @@ - (void)updateViewsAnimated:(BOOL)animated withDuration:(NSTimeInterval)duration // Move thumb position. CGPoint point = [self thumbPositionForValue:_value]; _thumbView.center = point; - _trackView.frame = - CGRectMake(0, self.center.y - (_trackHeight / 2), CGRectGetWidth(self.bounds), _trackHeight); + if (_trackEndsAreInset) { + _trackView.frame = + CGRectMake(_thumbView.cornerRadius, self.center.y - (_trackHeight / 2), + CGRectGetWidth(self.bounds) - (_thumbView.cornerRadius * 2), _trackHeight); + } else { + _trackView.frame = + CGRectMake(0, self.center.y - (_trackHeight / 2), CGRectGetWidth(self.bounds), _trackHeight); + } + [self updateTrackMask]; [self updateColorsAnimated:animated withDuration:duration]; } - (void)updateTrackMask { CGRect maskFrame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), _trackHeight); - if (_trackEndsAreInset) { - maskFrame = CGRectInset(maskFrame, _thumbView.cornerRadius, 0); - } CGMutablePathRef path = CGPathCreateMutable(); CGFloat cornerRadius = _trackHeight / 2; From 34019a8f8dfdd0fe8f1a34d075ce965d1affc5e3 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Tue, 7 Jun 2016 13:16:03 -0400 Subject: [PATCH 21/28] [CatalogByConvention] Rename CBCNodeViewController.h/m to match class name. Reviewers: O1 Material components iOS, ajsecord Reviewed By: O1 Material components iOS, ajsecord Tags: #material_components_ios Differential Revision: http://codereview.cc/D945 --- .../{CBCNodeViewController.h => CBCNodeListViewController.h} | 0 .../{CBCNodeViewController.m => CBCNodeListViewController.m} | 2 +- catalog/CatalogByConvention/src/CatalogByConvention.h | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename catalog/CatalogByConvention/src/{CBCNodeViewController.h => CBCNodeListViewController.h} (100%) rename catalog/CatalogByConvention/src/{CBCNodeViewController.m => CBCNodeListViewController.m} (99%) diff --git a/catalog/CatalogByConvention/src/CBCNodeViewController.h b/catalog/CatalogByConvention/src/CBCNodeListViewController.h similarity index 100% rename from catalog/CatalogByConvention/src/CBCNodeViewController.h rename to catalog/CatalogByConvention/src/CBCNodeListViewController.h diff --git a/catalog/CatalogByConvention/src/CBCNodeViewController.m b/catalog/CatalogByConvention/src/CBCNodeListViewController.m similarity index 99% rename from catalog/CatalogByConvention/src/CBCNodeViewController.m rename to catalog/CatalogByConvention/src/CBCNodeListViewController.m index 810113ce437..4fe158b9f72 100644 --- a/catalog/CatalogByConvention/src/CBCNodeViewController.m +++ b/catalog/CatalogByConvention/src/CBCNodeListViewController.m @@ -14,7 +14,7 @@ limitations under the License. */ -#import "CBCNodeViewController.h" +#import "CBCNodeListViewController.h" #import "CBCCatalogExample.h" #import "CBCRuntime.h" diff --git a/catalog/CatalogByConvention/src/CatalogByConvention.h b/catalog/CatalogByConvention/src/CatalogByConvention.h index 81c321c855a..f1975f2432d 100644 --- a/catalog/CatalogByConvention/src/CatalogByConvention.h +++ b/catalog/CatalogByConvention/src/CatalogByConvention.h @@ -14,4 +14,4 @@ limitations under the License. */ -#import "CBCNodeViewController.h" +#import "CBCNodeListViewController.h" From 9a08307975a0ea51d89a7e742451ef9113de7896 Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 11:14:17 -0400 Subject: [PATCH 22/28] [Catalog] fixed Xcode project missing file. Summary: Broken by file rename in http://codereview.cc/D945 Reviewers: erli, featherless, O1 Material components iOS, lpromero Reviewed By: featherless, O1 Material components iOS, lpromero Tags: #material_components_ios Differential Revision: http://codereview.cc/D948 --- catalog/MDCCatalog.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/catalog/MDCCatalog.xcodeproj/project.pbxproj b/catalog/MDCCatalog.xcodeproj/project.pbxproj index 922bf2b43a2..e62a91c564a 100644 --- a/catalog/MDCCatalog.xcodeproj/project.pbxproj +++ b/catalog/MDCCatalog.xcodeproj/project.pbxproj @@ -15,7 +15,7 @@ 664524BE1C6BA62A001ADBF8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 664524BD1C6BA62A001ADBF8 /* Assets.xcassets */; }; 664524C11C6BA62A001ADBF8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 664524BF1C6BA62A001ADBF8 /* LaunchScreen.storyboard */; }; 66519B071CCA980600E5423E /* MDCInkTouchController+Injection.m in Sources */ = {isa = PBXBuildFile; fileRef = 66519B061CCA980600E5423E /* MDCInkTouchController+Injection.m */; }; - 666CA70D1CAEBCA9001B1884 /* CBCNodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 666CA70A1CAEBCA9001B1884 /* CBCNodeViewController.m */; }; + 666CA70D1CAEBCA9001B1884 /* CBCNodeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 666CA70A1CAEBCA9001B1884 /* CBCNodeListViewController.m */; }; 6681FDFD1CC586660013A0C7 /* MDCCatalogTileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6681FDFC1CC586660013A0C7 /* MDCCatalogTileView.swift */; }; 75F4516F2130AB879A7EDBD5 /* Pods_MDCCatalog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A55EA1CC69E40D5EF866144 /* Pods_MDCCatalog.framework */; }; DE1944861CBD9E40009E0321 /* MDCCatalogTileData.m in Sources */ = {isa = PBXBuildFile; fileRef = DE1944681CBD9E40009E0321 /* MDCCatalogTileData.m */; }; @@ -88,8 +88,8 @@ 66519B061CCA980600E5423E /* MDCInkTouchController+Injection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MDCInkTouchController+Injection.m"; sourceTree = ""; }; 665A34D91C6BD01900962055 /* MDCCatalog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MDCCatalog-Bridging-Header.h"; sourceTree = ""; }; 666CA7081CAEBCA9001B1884 /* CBCCatalogExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CBCCatalogExample.h; sourceTree = ""; }; - 666CA7091CAEBCA9001B1884 /* CBCNodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CBCNodeViewController.h; sourceTree = ""; }; - 666CA70A1CAEBCA9001B1884 /* CBCNodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CBCNodeViewController.m; sourceTree = ""; }; + 666CA7091CAEBCA9001B1884 /* CBCNodeListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CBCNodeListViewController.h; sourceTree = ""; }; + 666CA70A1CAEBCA9001B1884 /* CBCNodeListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CBCNodeListViewController.m; sourceTree = ""; }; 6681FDFC1CC586660013A0C7 /* MDCCatalogTileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MDCCatalogTileView.swift; sourceTree = ""; }; 90B4FE989AA27838D0FB6A13 /* Pods-MDCCatalog.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MDCCatalog.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MDCCatalog/Pods-MDCCatalog.debug.xcconfig"; sourceTree = ""; }; C250A4553B960CD6E1604CB7 /* Pods-MDCCatalog.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MDCCatalog.release.xcconfig"; path = "Pods/Target Support Files/Pods-MDCCatalog/Pods-MDCCatalog.release.xcconfig"; sourceTree = ""; }; @@ -212,8 +212,8 @@ children = ( 3640411C1CBECABD00C962B2 /* CatalogByConvention.h */, 666CA7081CAEBCA9001B1884 /* CBCCatalogExample.h */, - 666CA7091CAEBCA9001B1884 /* CBCNodeViewController.h */, - 666CA70A1CAEBCA9001B1884 /* CBCNodeViewController.m */, + 666CA7091CAEBCA9001B1884 /* CBCNodeListViewController.h */, + 666CA70A1CAEBCA9001B1884 /* CBCNodeListViewController.m */, 6642AB7E1CBDBE0900F5B1D7 /* private */, ); name = CatalogByConvention; @@ -434,7 +434,7 @@ files = ( DE1944901CBD9E40009E0321 /* MDCCatalogTileDataShadowLayer.m in Sources */, 6642AB811CBDBE0900F5B1D7 /* CBCRuntime.m in Sources */, - 666CA70D1CAEBCA9001B1884 /* CBCNodeViewController.m in Sources */, + 666CA70D1CAEBCA9001B1884 /* CBCNodeListViewController.m in Sources */, DE1944911CBD9E40009E0321 /* MDCCatalogTileDataSlider.m in Sources */, DE19448E1CBD9E40009E0321 /* MDCCatalogTileDataNavigationBar.m in Sources */, DE19448F1CBD9E40009E0321 /* MDCCatalogTileDataPageControl.m in Sources */, From 5f72fb33639710149fcccfc66a8eb1778600244e Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 11:31:04 -0400 Subject: [PATCH 23/28] Cut new release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7914ed55cdd..929ecebb8e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# release-candidate TODO: Replace me with version number. + # 10.0.0 ## Infrastructure From 5322f8601c24280f32be0991e3c71000862ad3eb Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 11:38:11 -0400 Subject: [PATCH 24/28] Added API diff to CHANGELOG.md. --- CHANGELOG.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 929ecebb8e1..df9c6bba1fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,41 @@ -# release-candidate TODO: Replace me with version number. +# release-candidate TODO: Replace me with version number. + +## API diffs + +Auto-generated by running: + + scripts/api_diff -o dc74cd290f327e950eab32b48f3105c55972fad9 -n d4a3ac376f5c8498cfb52401f4fbb69d2e318897 + +### ActivityIndicator + +**New component.** + +### FontDiskLoader + +- [new] [`-[MDCFontDiskLoader unregisterFont]`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L84) +- [property attribute change] [`MDCFontDiskLoader.hasFailedRegistration`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L100). +Added *readonly*. +- [property attribute change] [`MDCFontDiskLoader.isRegistered`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L93). +Added *readonly*. +- [protocols changed] [`MDCFontDiskLoader`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L28). +Added *NSCopying*. +- [modified] [`-[MDCFontDiskLoader setHasFailedRegistration:]`](https://github.com/google/material-components-ios/blob/dc74cd290f327e950eab32b48f3105c55972fad9/components/FontDiskLoader/src/MDCFontDiskLoader.h#L109) + +| From | To | Kind | +|:---- |:-- |:---- | +| `@property (nonatomic) BOOL hasFailedRegistration` | `- (void)setHasFailedRegistration:(BOOL)hasFailedRegistration` | `declaration` | +| `Available` | `Deprecated` | `availability` | +| `` | `This setter is no longer public` | `deprecationMessage` | + +- [modified] [`-[MDCFontDiskLoader setIsRegistered:]`](https://github.com/google/material-components-ios/blob/dc74cd290f327e950eab32b48f3105c55972fad9/components/FontDiskLoader/src/MDCFontDiskLoader.h#L108) + +| From | To | Kind | +|:---- |:-- |:---- | +| `@property (nonatomic) BOOL isRegistered` | `- (void)setIsRegistered:(BOOL)isRegistered` | `declaration` | +| `Available` | `Deprecated` | `availability` | +| `` | `This setter is no longer public` | `deprecationMessage` | + + # 10.0.0 From 921d58688501b33b0ae10e9c84933affcfec2e4a Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 11:41:43 -0400 Subject: [PATCH 25/28] Added commit changes to CHANGELOG.md. --- CHANGELOG.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df9c6bba1fe..d14459517dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,75 @@ Added *NSCopying*. | `Available` | `Deprecated` | `availability` | | `` | `This setter is no longer public` | `deprecationMessage` | +## Component changes + +### ActivityIndicator + +#### Changes + +* [Adding activity indicator component and demo](https://github.com/google/material-components-ios/commit/d589b27330d717c9d7a4bd1ebea562453f5c5639) (Junius Gunaratne) +* [Move layout code into supplemental, support landscape mode](https://github.com/google/material-components-ios/commit/06acbe8cb8b9aa0befea566233f5e7b7528dd8dd) (Junius Gunaratne) + +### AppBar + +#### Changes + +* [Fix typo in back item accessibility identifier.](https://github.com/google/material-components-ios/commit/f5a6ce7244edd1ad67fc8a04a0a087623936db32) (Louis Romero) +* [Respect the navigation bar's layout direction](https://github.com/google/material-components-ios/commit/c60de65ffdef1cf83d664e429615b87238f15ccf) (Louis Romero) +* [Set an accessibility identifier on the default back button.](https://github.com/google/material-components-ios/commit/ae21fd0453b3f932e2926a14518009429190c39c) (Louis Romero) + +### ButtonBar + +#### Changes + +* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) + +### Buttons + +#### Changes + +* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) + +### Collections + +#### Changes + +* [Fixes bug when initializing collection view with own layout.](https://github.com/google/material-components-ios/commit/306da8d238cfd9d85f65ccb33370e1c6485418a1) (Chris Cox) + +### FontDiskLoader + +#### Changes + +* [Added unregisterFont method.](https://github.com/google/material-components-ios/commit/77d8ebcd78cf37b9e38b77c5b29136ee37d6f719) (randallli) +* [Correct Roboto Font markdown for design specification link.](https://github.com/google/material-components-ios/commit/fa55cdd03099dfb2822e76222e81f631f7e000d0) (Yiran Mao) +* [[FontDiskLoader]? added warning NSLog when failing to load the font by name.](https://github.com/google/material-components-ios/commit/d62b6dc116d8db90e1f1953c48c0e8b6c45949de) (randallli) +* [[MDCFontDiskLoader] Added copying protocol](https://github.com/google/material-components-ios/commit/7a0a9f0aaa61d47a780fd404916701f373f7e53d) (randallli) +* [[MDCFontDiskLoader] sharing registered state across all instances of objects.](https://github.com/google/material-components-ios/commit/1ef21ea7e080664050271576fd85dcea3c4d87b4) (randallli) +* [[MDCFontDiskLoader]? Deprecated properties that should not have been public write.](https://github.com/google/material-components-ios/commit/25f4d7caec33172ef9aafc1c633c03740da62d16) (randallli) + +### PageControl + +#### Changes + +* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) + +### RobotoFontLoader + +#### Changes + +* [Correct Roboto Font markdown for design specification link.](https://github.com/google/material-components-ios/commit/fa55cdd03099dfb2822e76222e81f631f7e000d0) (Yiran Mao) + +### ShadowLayer + +#### Changes + +* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) + +### Switch + +#### Changes +* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) # 10.0.0 From 4fa73ec1c7976557ae106c317eeb24aba499f008 Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 11:53:11 -0400 Subject: [PATCH 26/28] Hand-modified CHANGELOG.md API diff. --- CHANGELOG.md | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d14459517dc..b2854267028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,26 +14,11 @@ Auto-generated by running: - [new] [`-[MDCFontDiskLoader unregisterFont]`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L84) - [property attribute change] [`MDCFontDiskLoader.hasFailedRegistration`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L100). -Added *readonly*. +Deprecated setter. - [property attribute change] [`MDCFontDiskLoader.isRegistered`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L93). -Added *readonly*. +Deprecated setter. - [protocols changed] [`MDCFontDiskLoader`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L28). Added *NSCopying*. -- [modified] [`-[MDCFontDiskLoader setHasFailedRegistration:]`](https://github.com/google/material-components-ios/blob/dc74cd290f327e950eab32b48f3105c55972fad9/components/FontDiskLoader/src/MDCFontDiskLoader.h#L109) - -| From | To | Kind | -|:---- |:-- |:---- | -| `@property (nonatomic) BOOL hasFailedRegistration` | `- (void)setHasFailedRegistration:(BOOL)hasFailedRegistration` | `declaration` | -| `Available` | `Deprecated` | `availability` | -| `` | `This setter is no longer public` | `deprecationMessage` | - -- [modified] [`-[MDCFontDiskLoader setIsRegistered:]`](https://github.com/google/material-components-ios/blob/dc74cd290f327e950eab32b48f3105c55972fad9/components/FontDiskLoader/src/MDCFontDiskLoader.h#L108) - -| From | To | Kind | -|:---- |:-- |:---- | -| `@property (nonatomic) BOOL isRegistered` | `- (void)setIsRegistered:(BOOL)isRegistered` | `declaration` | -| `Available` | `Deprecated` | `availability` | -| `` | `This setter is no longer public` | `deprecationMessage` | ## Component changes From 32934941b42da1ba93e20ab116ff4a0b16c95eb0 Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 11:57:34 -0400 Subject: [PATCH 27/28] Bumped version number to 10.1.0. --- CHANGELOG.md | 3 +- MaterialComponents.podspec | 2 +- MaterialComponentsCatalog.podspec | 2 +- MaterialComponentsUnitTests.podspec | 2 +- catalog/Podfile.lock | 144 ++++++++++++++-------------- demos/Pesto/Podfile.lock | 136 +++++++++++++------------- demos/Shrine/Podfile.lock | 136 +++++++++++++------------- 7 files changed, 213 insertions(+), 212 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2854267028..eb4886f1209 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# release-candidate TODO: Replace me with version number. +# 10.1.0 ## API diffs @@ -18,6 +18,7 @@ Deprecated setter. - [property attribute change] [`MDCFontDiskLoader.isRegistered`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L93). Deprecated setter. - [protocols changed] [`MDCFontDiskLoader`](https://github.com/google/material-components-ios/blob/d4a3ac376f5c8498cfb52401f4fbb69d2e318897/components/FontDiskLoader/src/MDCFontDiskLoader.h#L28). + Added *NSCopying*. ## Component changes diff --git a/MaterialComponents.podspec b/MaterialComponents.podspec index d31840de27c..7ef4e77ee4d 100644 --- a/MaterialComponents.podspec +++ b/MaterialComponents.podspec @@ -2,7 +2,7 @@ load 'scripts/generated/icons.rb' Pod::Spec.new do |s| s.name = "MaterialComponents" - s.version = "10.0.0" + s.version = "10.1.0" s.authors = { 'Apple platform engineering at Google' => 'appleplatforms@google.com' } s.summary = "A collection of stand-alone production-ready UI libraries focused on design details." s.homepage = "https://github.com/google/material-components-ios" diff --git a/MaterialComponentsCatalog.podspec b/MaterialComponentsCatalog.podspec index 9cc1281ec3b..53b4d8507be 100644 --- a/MaterialComponentsCatalog.podspec +++ b/MaterialComponentsCatalog.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "MaterialComponentsCatalog" - s.version = "10.0.0" + s.version = "10.1.0" s.authors = { 'Apple platform engineering at Google' => 'appleplatforms@google.com' } s.summary = "A collection of stand-alone production-ready UI libraries focused on design details." s.homepage = "https://github.com/google/material-components-ios" diff --git a/MaterialComponentsUnitTests.podspec b/MaterialComponentsUnitTests.podspec index 8e47f4bb319..25d8ab99438 100644 --- a/MaterialComponentsUnitTests.podspec +++ b/MaterialComponentsUnitTests.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "MaterialComponentsUnitTests" - s.version = "10.0.0" + s.version = "10.1.0" s.authors = { 'Apple platform engineering at Google' => 'appleplatforms@google.com' } s.summary = "A collection of stand-alone production-ready UI libraries focused on design details." s.homepage = "https://github.com/google/material-components-ios" diff --git a/catalog/Podfile.lock b/catalog/Podfile.lock index 46a1cc7aced..88e7c852dbf 100644 --- a/catalog/Podfile.lock +++ b/catalog/Podfile.lock @@ -1,29 +1,29 @@ PODS: - - MaterialComponents (10.0.0): - - MaterialComponents/ActivityIndicator (= 10.0.0) - - MaterialComponents/AppBar (= 10.0.0) - - MaterialComponents/ButtonBar (= 10.0.0) - - MaterialComponents/Buttons (= 10.0.0) - - MaterialComponents/CollectionCells (= 10.0.0) - - MaterialComponents/CollectionLayoutAttributes (= 10.0.0) - - MaterialComponents/Collections (= 10.0.0) - - MaterialComponents/FlexibleHeader (= 10.0.0) - - MaterialComponents/FontDiskLoader (= 10.0.0) - - MaterialComponents/HeaderStackView (= 10.0.0) - - MaterialComponents/Ink (= 10.0.0) - - MaterialComponents/NavigationBar (= 10.0.0) - - MaterialComponents/PageControl (= 10.0.0) - - MaterialComponents/Palettes (= 10.0.0) - - MaterialComponents/private (= 10.0.0) - - MaterialComponents/RobotoFontLoader (= 10.0.0) - - MaterialComponents/ShadowElevations (= 10.0.0) - - MaterialComponents/ShadowLayer (= 10.0.0) - - MaterialComponents/Slider (= 10.0.0) - - MaterialComponents/SpritedAnimationView (= 10.0.0) - - MaterialComponents/Switch (= 10.0.0) - - MaterialComponents/Typography (= 10.0.0) - - MaterialComponents/ActivityIndicator (10.0.0) - - MaterialComponents/AppBar (10.0.0): + - MaterialComponents (10.1.0): + - MaterialComponents/ActivityIndicator (= 10.1.0) + - MaterialComponents/AppBar (= 10.1.0) + - MaterialComponents/ButtonBar (= 10.1.0) + - MaterialComponents/Buttons (= 10.1.0) + - MaterialComponents/CollectionCells (= 10.1.0) + - MaterialComponents/CollectionLayoutAttributes (= 10.1.0) + - MaterialComponents/Collections (= 10.1.0) + - MaterialComponents/FlexibleHeader (= 10.1.0) + - MaterialComponents/FontDiskLoader (= 10.1.0) + - MaterialComponents/HeaderStackView (= 10.1.0) + - MaterialComponents/Ink (= 10.1.0) + - MaterialComponents/NavigationBar (= 10.1.0) + - MaterialComponents/PageControl (= 10.1.0) + - MaterialComponents/Palettes (= 10.1.0) + - MaterialComponents/private (= 10.1.0) + - MaterialComponents/RobotoFontLoader (= 10.1.0) + - MaterialComponents/ShadowElevations (= 10.1.0) + - MaterialComponents/ShadowLayer (= 10.1.0) + - MaterialComponents/Slider (= 10.1.0) + - MaterialComponents/SpritedAnimationView (= 10.1.0) + - MaterialComponents/Switch (= 10.1.0) + - MaterialComponents/Typography (= 10.1.0) + - MaterialComponents/ActivityIndicator (10.1.0) + - MaterialComponents/AppBar (10.1.0): - MaterialComponents/FlexibleHeader - MaterialComponents/HeaderStackView - MaterialComponents/NavigationBar @@ -31,14 +31,14 @@ PODS: - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/ButtonBar (10.0.0): + - MaterialComponents/ButtonBar (10.1.0): - MaterialComponents/Buttons - - MaterialComponents/Buttons (10.0.0): + - MaterialComponents/Buttons (10.1.0): - MaterialComponents/Ink - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/CollectionCells (10.0.0): + - MaterialComponents/CollectionCells (10.1.0): - MaterialComponents/CollectionLayoutAttributes - MaterialComponents/Ink - MaterialComponents/private/Icons/ic_check @@ -48,71 +48,71 @@ PODS: - MaterialComponents/private/Icons/ic_radio_button_unchecked - MaterialComponents/private/Icons/ic_reorder - MaterialComponents/Typography - - MaterialComponents/CollectionLayoutAttributes (10.0.0) - - MaterialComponents/Collections (10.0.0): + - MaterialComponents/CollectionLayoutAttributes (10.1.0) + - MaterialComponents/Collections (10.1.0): - MaterialComponents/CollectionCells - MaterialComponents/CollectionLayoutAttributes - MaterialComponents/Ink - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/FlexibleHeader (10.0.0) - - MaterialComponents/FontDiskLoader (10.0.0) - - MaterialComponents/HeaderStackView (10.0.0) - - MaterialComponents/Ink (10.0.0) - - MaterialComponents/NavigationBar (10.0.0): + - MaterialComponents/FlexibleHeader (10.1.0) + - MaterialComponents/FontDiskLoader (10.1.0) + - MaterialComponents/HeaderStackView (10.1.0) + - MaterialComponents/Ink (10.1.0) + - MaterialComponents/NavigationBar (10.1.0): - MaterialComponents/ButtonBar - MaterialComponents/Typography - - MaterialComponents/PageControl (10.0.0) - - MaterialComponents/Palettes (10.0.0) - - MaterialComponents/private (10.0.0): - - MaterialComponents/private/Color (= 10.0.0) - - MaterialComponents/private/Icons (= 10.0.0) - - MaterialComponents/private/ThumbTrack (= 10.0.0) - - MaterialComponents/private/Color (10.0.0) - - MaterialComponents/private/Icons (10.0.0): - - MaterialComponents/private/Icons/Base (= 10.0.0) - - MaterialComponents/private/Icons/ic_arrow_back (= 10.0.0) - - MaterialComponents/private/Icons/ic_check (= 10.0.0) - - MaterialComponents/private/Icons/ic_check_circle (= 10.0.0) - - MaterialComponents/private/Icons/ic_chevron_right (= 10.0.0) - - MaterialComponents/private/Icons/ic_info (= 10.0.0) - - MaterialComponents/private/Icons/ic_radio_button_unchecked (= 10.0.0) - - MaterialComponents/private/Icons/ic_reorder (= 10.0.0) - - MaterialComponents/private/Icons/Base (10.0.0) - - MaterialComponents/private/Icons/ic_arrow_back (10.0.0): + - MaterialComponents/PageControl (10.1.0) + - MaterialComponents/Palettes (10.1.0) + - MaterialComponents/private (10.1.0): + - MaterialComponents/private/Color (= 10.1.0) + - MaterialComponents/private/Icons (= 10.1.0) + - MaterialComponents/private/ThumbTrack (= 10.1.0) + - MaterialComponents/private/Color (10.1.0) + - MaterialComponents/private/Icons (10.1.0): + - MaterialComponents/private/Icons/Base (= 10.1.0) + - MaterialComponents/private/Icons/ic_arrow_back (= 10.1.0) + - MaterialComponents/private/Icons/ic_check (= 10.1.0) + - MaterialComponents/private/Icons/ic_check_circle (= 10.1.0) + - MaterialComponents/private/Icons/ic_chevron_right (= 10.1.0) + - MaterialComponents/private/Icons/ic_info (= 10.1.0) + - MaterialComponents/private/Icons/ic_radio_button_unchecked (= 10.1.0) + - MaterialComponents/private/Icons/ic_reorder (= 10.1.0) + - MaterialComponents/private/Icons/Base (10.1.0) + - MaterialComponents/private/Icons/ic_arrow_back (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_check (10.0.0): + - MaterialComponents/private/Icons/ic_check (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_check_circle (10.0.0): + - MaterialComponents/private/Icons/ic_check_circle (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_chevron_right (10.0.0): + - MaterialComponents/private/Icons/ic_chevron_right (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_info (10.0.0): + - MaterialComponents/private/Icons/ic_info (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_radio_button_unchecked (10.0.0): + - MaterialComponents/private/Icons/ic_radio_button_unchecked (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_reorder (10.0.0): + - MaterialComponents/private/Icons/ic_reorder (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/ThumbTrack (10.0.0): + - MaterialComponents/private/ThumbTrack (10.1.0): - MaterialComponents/Ink - MaterialComponents/private/Color - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - - MaterialComponents/RobotoFontLoader (10.0.0): + - MaterialComponents/RobotoFontLoader (10.1.0): - MaterialComponents/FontDiskLoader - MaterialComponents/Typography - - MaterialComponents/ShadowElevations (10.0.0) - - MaterialComponents/ShadowLayer (10.0.0) - - MaterialComponents/Slider (10.0.0): + - MaterialComponents/ShadowElevations (10.1.0) + - MaterialComponents/ShadowLayer (10.1.0) + - MaterialComponents/Slider (10.1.0): - MaterialComponents/private/ThumbTrack - - MaterialComponents/SpritedAnimationView (10.0.0) - - MaterialComponents/Switch (10.0.0): + - MaterialComponents/SpritedAnimationView (10.1.0) + - MaterialComponents/Switch (10.1.0): - MaterialComponents/private/ThumbTrack - - MaterialComponents/Typography (10.0.0) - - MaterialComponentsCatalog (10.0.0): + - MaterialComponents/Typography (10.1.0) + - MaterialComponentsCatalog (10.1.0): - MaterialComponents - - MaterialComponentsUnitTests (10.0.0): + - MaterialComponentsUnitTests (10.1.0): - MaterialComponents DEPENDENCIES: @@ -129,9 +129,9 @@ EXTERNAL SOURCES: :path: ../ SPEC CHECKSUMS: - MaterialComponents: 9c573b7371abd74208fe05a1915f3f02f513a009 - MaterialComponentsCatalog: c665fdd39bff9621608cec8fe0a99e44ce8e7a13 - MaterialComponentsUnitTests: 66c55d81bb08daf37915f7142244bfeaa04a4776 + MaterialComponents: 65ac94f1904a9ddd867b95c2f3c55222943fd4fa + MaterialComponentsCatalog: 7d6fe07bb1e0967a4e84d6f804a846a14152e644 + MaterialComponentsUnitTests: 91fe0738eab0388318dc4b8be9c15790a35c2081 PODFILE CHECKSUM: 859f7856fc0fa049789dc17023b9f6f887fb1be9 diff --git a/demos/Pesto/Podfile.lock b/demos/Pesto/Podfile.lock index 610df1d31c7..ec43419cc15 100644 --- a/demos/Pesto/Podfile.lock +++ b/demos/Pesto/Podfile.lock @@ -1,29 +1,29 @@ PODS: - - MaterialComponents (10.0.0): - - MaterialComponents/ActivityIndicator (= 10.0.0) - - MaterialComponents/AppBar (= 10.0.0) - - MaterialComponents/ButtonBar (= 10.0.0) - - MaterialComponents/Buttons (= 10.0.0) - - MaterialComponents/CollectionCells (= 10.0.0) - - MaterialComponents/CollectionLayoutAttributes (= 10.0.0) - - MaterialComponents/Collections (= 10.0.0) - - MaterialComponents/FlexibleHeader (= 10.0.0) - - MaterialComponents/FontDiskLoader (= 10.0.0) - - MaterialComponents/HeaderStackView (= 10.0.0) - - MaterialComponents/Ink (= 10.0.0) - - MaterialComponents/NavigationBar (= 10.0.0) - - MaterialComponents/PageControl (= 10.0.0) - - MaterialComponents/Palettes (= 10.0.0) - - MaterialComponents/private (= 10.0.0) - - MaterialComponents/RobotoFontLoader (= 10.0.0) - - MaterialComponents/ShadowElevations (= 10.0.0) - - MaterialComponents/ShadowLayer (= 10.0.0) - - MaterialComponents/Slider (= 10.0.0) - - MaterialComponents/SpritedAnimationView (= 10.0.0) - - MaterialComponents/Switch (= 10.0.0) - - MaterialComponents/Typography (= 10.0.0) - - MaterialComponents/ActivityIndicator (10.0.0) - - MaterialComponents/AppBar (10.0.0): + - MaterialComponents (10.1.0): + - MaterialComponents/ActivityIndicator (= 10.1.0) + - MaterialComponents/AppBar (= 10.1.0) + - MaterialComponents/ButtonBar (= 10.1.0) + - MaterialComponents/Buttons (= 10.1.0) + - MaterialComponents/CollectionCells (= 10.1.0) + - MaterialComponents/CollectionLayoutAttributes (= 10.1.0) + - MaterialComponents/Collections (= 10.1.0) + - MaterialComponents/FlexibleHeader (= 10.1.0) + - MaterialComponents/FontDiskLoader (= 10.1.0) + - MaterialComponents/HeaderStackView (= 10.1.0) + - MaterialComponents/Ink (= 10.1.0) + - MaterialComponents/NavigationBar (= 10.1.0) + - MaterialComponents/PageControl (= 10.1.0) + - MaterialComponents/Palettes (= 10.1.0) + - MaterialComponents/private (= 10.1.0) + - MaterialComponents/RobotoFontLoader (= 10.1.0) + - MaterialComponents/ShadowElevations (= 10.1.0) + - MaterialComponents/ShadowLayer (= 10.1.0) + - MaterialComponents/Slider (= 10.1.0) + - MaterialComponents/SpritedAnimationView (= 10.1.0) + - MaterialComponents/Switch (= 10.1.0) + - MaterialComponents/Typography (= 10.1.0) + - MaterialComponents/ActivityIndicator (10.1.0) + - MaterialComponents/AppBar (10.1.0): - MaterialComponents/FlexibleHeader - MaterialComponents/HeaderStackView - MaterialComponents/NavigationBar @@ -31,14 +31,14 @@ PODS: - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/ButtonBar (10.0.0): + - MaterialComponents/ButtonBar (10.1.0): - MaterialComponents/Buttons - - MaterialComponents/Buttons (10.0.0): + - MaterialComponents/Buttons (10.1.0): - MaterialComponents/Ink - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/CollectionCells (10.0.0): + - MaterialComponents/CollectionCells (10.1.0): - MaterialComponents/CollectionLayoutAttributes - MaterialComponents/Ink - MaterialComponents/private/Icons/ic_check @@ -48,68 +48,68 @@ PODS: - MaterialComponents/private/Icons/ic_radio_button_unchecked - MaterialComponents/private/Icons/ic_reorder - MaterialComponents/Typography - - MaterialComponents/CollectionLayoutAttributes (10.0.0) - - MaterialComponents/Collections (10.0.0): + - MaterialComponents/CollectionLayoutAttributes (10.1.0) + - MaterialComponents/Collections (10.1.0): - MaterialComponents/CollectionCells - MaterialComponents/CollectionLayoutAttributes - MaterialComponents/Ink - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/FlexibleHeader (10.0.0) - - MaterialComponents/FontDiskLoader (10.0.0) - - MaterialComponents/HeaderStackView (10.0.0) - - MaterialComponents/Ink (10.0.0) - - MaterialComponents/NavigationBar (10.0.0): + - MaterialComponents/FlexibleHeader (10.1.0) + - MaterialComponents/FontDiskLoader (10.1.0) + - MaterialComponents/HeaderStackView (10.1.0) + - MaterialComponents/Ink (10.1.0) + - MaterialComponents/NavigationBar (10.1.0): - MaterialComponents/ButtonBar - MaterialComponents/Typography - - MaterialComponents/PageControl (10.0.0) - - MaterialComponents/Palettes (10.0.0) - - MaterialComponents/private (10.0.0): - - MaterialComponents/private/Color (= 10.0.0) - - MaterialComponents/private/Icons (= 10.0.0) - - MaterialComponents/private/ThumbTrack (= 10.0.0) - - MaterialComponents/private/Color (10.0.0) - - MaterialComponents/private/Icons (10.0.0): - - MaterialComponents/private/Icons/Base (= 10.0.0) - - MaterialComponents/private/Icons/ic_arrow_back (= 10.0.0) - - MaterialComponents/private/Icons/ic_check (= 10.0.0) - - MaterialComponents/private/Icons/ic_check_circle (= 10.0.0) - - MaterialComponents/private/Icons/ic_chevron_right (= 10.0.0) - - MaterialComponents/private/Icons/ic_info (= 10.0.0) - - MaterialComponents/private/Icons/ic_radio_button_unchecked (= 10.0.0) - - MaterialComponents/private/Icons/ic_reorder (= 10.0.0) - - MaterialComponents/private/Icons/Base (10.0.0) - - MaterialComponents/private/Icons/ic_arrow_back (10.0.0): + - MaterialComponents/PageControl (10.1.0) + - MaterialComponents/Palettes (10.1.0) + - MaterialComponents/private (10.1.0): + - MaterialComponents/private/Color (= 10.1.0) + - MaterialComponents/private/Icons (= 10.1.0) + - MaterialComponents/private/ThumbTrack (= 10.1.0) + - MaterialComponents/private/Color (10.1.0) + - MaterialComponents/private/Icons (10.1.0): + - MaterialComponents/private/Icons/Base (= 10.1.0) + - MaterialComponents/private/Icons/ic_arrow_back (= 10.1.0) + - MaterialComponents/private/Icons/ic_check (= 10.1.0) + - MaterialComponents/private/Icons/ic_check_circle (= 10.1.0) + - MaterialComponents/private/Icons/ic_chevron_right (= 10.1.0) + - MaterialComponents/private/Icons/ic_info (= 10.1.0) + - MaterialComponents/private/Icons/ic_radio_button_unchecked (= 10.1.0) + - MaterialComponents/private/Icons/ic_reorder (= 10.1.0) + - MaterialComponents/private/Icons/Base (10.1.0) + - MaterialComponents/private/Icons/ic_arrow_back (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_check (10.0.0): + - MaterialComponents/private/Icons/ic_check (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_check_circle (10.0.0): + - MaterialComponents/private/Icons/ic_check_circle (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_chevron_right (10.0.0): + - MaterialComponents/private/Icons/ic_chevron_right (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_info (10.0.0): + - MaterialComponents/private/Icons/ic_info (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_radio_button_unchecked (10.0.0): + - MaterialComponents/private/Icons/ic_radio_button_unchecked (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_reorder (10.0.0): + - MaterialComponents/private/Icons/ic_reorder (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/ThumbTrack (10.0.0): + - MaterialComponents/private/ThumbTrack (10.1.0): - MaterialComponents/Ink - MaterialComponents/private/Color - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - - MaterialComponents/RobotoFontLoader (10.0.0): + - MaterialComponents/RobotoFontLoader (10.1.0): - MaterialComponents/FontDiskLoader - MaterialComponents/Typography - - MaterialComponents/ShadowElevations (10.0.0) - - MaterialComponents/ShadowLayer (10.0.0) - - MaterialComponents/Slider (10.0.0): + - MaterialComponents/ShadowElevations (10.1.0) + - MaterialComponents/ShadowLayer (10.1.0) + - MaterialComponents/Slider (10.1.0): - MaterialComponents/private/ThumbTrack - - MaterialComponents/SpritedAnimationView (10.0.0) - - MaterialComponents/Switch (10.0.0): + - MaterialComponents/SpritedAnimationView (10.1.0) + - MaterialComponents/Switch (10.1.0): - MaterialComponents/private/ThumbTrack - - MaterialComponents/Typography (10.0.0) + - MaterialComponents/Typography (10.1.0) DEPENDENCIES: - MaterialComponents (from `../../`) @@ -119,7 +119,7 @@ EXTERNAL SOURCES: :path: ../../ SPEC CHECKSUMS: - MaterialComponents: 9c573b7371abd74208fe05a1915f3f02f513a009 + MaterialComponents: 65ac94f1904a9ddd867b95c2f3c55222943fd4fa PODFILE CHECKSUM: f138be16d4835113ff672258fc7529fad3f90e91 diff --git a/demos/Shrine/Podfile.lock b/demos/Shrine/Podfile.lock index fa40a3e7fe8..82b32990803 100644 --- a/demos/Shrine/Podfile.lock +++ b/demos/Shrine/Podfile.lock @@ -1,29 +1,29 @@ PODS: - - MaterialComponents (10.0.0): - - MaterialComponents/ActivityIndicator (= 10.0.0) - - MaterialComponents/AppBar (= 10.0.0) - - MaterialComponents/ButtonBar (= 10.0.0) - - MaterialComponents/Buttons (= 10.0.0) - - MaterialComponents/CollectionCells (= 10.0.0) - - MaterialComponents/CollectionLayoutAttributes (= 10.0.0) - - MaterialComponents/Collections (= 10.0.0) - - MaterialComponents/FlexibleHeader (= 10.0.0) - - MaterialComponents/FontDiskLoader (= 10.0.0) - - MaterialComponents/HeaderStackView (= 10.0.0) - - MaterialComponents/Ink (= 10.0.0) - - MaterialComponents/NavigationBar (= 10.0.0) - - MaterialComponents/PageControl (= 10.0.0) - - MaterialComponents/Palettes (= 10.0.0) - - MaterialComponents/private (= 10.0.0) - - MaterialComponents/RobotoFontLoader (= 10.0.0) - - MaterialComponents/ShadowElevations (= 10.0.0) - - MaterialComponents/ShadowLayer (= 10.0.0) - - MaterialComponents/Slider (= 10.0.0) - - MaterialComponents/SpritedAnimationView (= 10.0.0) - - MaterialComponents/Switch (= 10.0.0) - - MaterialComponents/Typography (= 10.0.0) - - MaterialComponents/ActivityIndicator (10.0.0) - - MaterialComponents/AppBar (10.0.0): + - MaterialComponents (10.1.0): + - MaterialComponents/ActivityIndicator (= 10.1.0) + - MaterialComponents/AppBar (= 10.1.0) + - MaterialComponents/ButtonBar (= 10.1.0) + - MaterialComponents/Buttons (= 10.1.0) + - MaterialComponents/CollectionCells (= 10.1.0) + - MaterialComponents/CollectionLayoutAttributes (= 10.1.0) + - MaterialComponents/Collections (= 10.1.0) + - MaterialComponents/FlexibleHeader (= 10.1.0) + - MaterialComponents/FontDiskLoader (= 10.1.0) + - MaterialComponents/HeaderStackView (= 10.1.0) + - MaterialComponents/Ink (= 10.1.0) + - MaterialComponents/NavigationBar (= 10.1.0) + - MaterialComponents/PageControl (= 10.1.0) + - MaterialComponents/Palettes (= 10.1.0) + - MaterialComponents/private (= 10.1.0) + - MaterialComponents/RobotoFontLoader (= 10.1.0) + - MaterialComponents/ShadowElevations (= 10.1.0) + - MaterialComponents/ShadowLayer (= 10.1.0) + - MaterialComponents/Slider (= 10.1.0) + - MaterialComponents/SpritedAnimationView (= 10.1.0) + - MaterialComponents/Switch (= 10.1.0) + - MaterialComponents/Typography (= 10.1.0) + - MaterialComponents/ActivityIndicator (10.1.0) + - MaterialComponents/AppBar (10.1.0): - MaterialComponents/FlexibleHeader - MaterialComponents/HeaderStackView - MaterialComponents/NavigationBar @@ -31,14 +31,14 @@ PODS: - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/ButtonBar (10.0.0): + - MaterialComponents/ButtonBar (10.1.0): - MaterialComponents/Buttons - - MaterialComponents/Buttons (10.0.0): + - MaterialComponents/Buttons (10.1.0): - MaterialComponents/Ink - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/CollectionCells (10.0.0): + - MaterialComponents/CollectionCells (10.1.0): - MaterialComponents/CollectionLayoutAttributes - MaterialComponents/Ink - MaterialComponents/private/Icons/ic_check @@ -48,68 +48,68 @@ PODS: - MaterialComponents/private/Icons/ic_radio_button_unchecked - MaterialComponents/private/Icons/ic_reorder - MaterialComponents/Typography - - MaterialComponents/CollectionLayoutAttributes (10.0.0) - - MaterialComponents/Collections (10.0.0): + - MaterialComponents/CollectionLayoutAttributes (10.1.0) + - MaterialComponents/Collections (10.1.0): - MaterialComponents/CollectionCells - MaterialComponents/CollectionLayoutAttributes - MaterialComponents/Ink - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - MaterialComponents/Typography - - MaterialComponents/FlexibleHeader (10.0.0) - - MaterialComponents/FontDiskLoader (10.0.0) - - MaterialComponents/HeaderStackView (10.0.0) - - MaterialComponents/Ink (10.0.0) - - MaterialComponents/NavigationBar (10.0.0): + - MaterialComponents/FlexibleHeader (10.1.0) + - MaterialComponents/FontDiskLoader (10.1.0) + - MaterialComponents/HeaderStackView (10.1.0) + - MaterialComponents/Ink (10.1.0) + - MaterialComponents/NavigationBar (10.1.0): - MaterialComponents/ButtonBar - MaterialComponents/Typography - - MaterialComponents/PageControl (10.0.0) - - MaterialComponents/Palettes (10.0.0) - - MaterialComponents/private (10.0.0): - - MaterialComponents/private/Color (= 10.0.0) - - MaterialComponents/private/Icons (= 10.0.0) - - MaterialComponents/private/ThumbTrack (= 10.0.0) - - MaterialComponents/private/Color (10.0.0) - - MaterialComponents/private/Icons (10.0.0): - - MaterialComponents/private/Icons/Base (= 10.0.0) - - MaterialComponents/private/Icons/ic_arrow_back (= 10.0.0) - - MaterialComponents/private/Icons/ic_check (= 10.0.0) - - MaterialComponents/private/Icons/ic_check_circle (= 10.0.0) - - MaterialComponents/private/Icons/ic_chevron_right (= 10.0.0) - - MaterialComponents/private/Icons/ic_info (= 10.0.0) - - MaterialComponents/private/Icons/ic_radio_button_unchecked (= 10.0.0) - - MaterialComponents/private/Icons/ic_reorder (= 10.0.0) - - MaterialComponents/private/Icons/Base (10.0.0) - - MaterialComponents/private/Icons/ic_arrow_back (10.0.0): + - MaterialComponents/PageControl (10.1.0) + - MaterialComponents/Palettes (10.1.0) + - MaterialComponents/private (10.1.0): + - MaterialComponents/private/Color (= 10.1.0) + - MaterialComponents/private/Icons (= 10.1.0) + - MaterialComponents/private/ThumbTrack (= 10.1.0) + - MaterialComponents/private/Color (10.1.0) + - MaterialComponents/private/Icons (10.1.0): + - MaterialComponents/private/Icons/Base (= 10.1.0) + - MaterialComponents/private/Icons/ic_arrow_back (= 10.1.0) + - MaterialComponents/private/Icons/ic_check (= 10.1.0) + - MaterialComponents/private/Icons/ic_check_circle (= 10.1.0) + - MaterialComponents/private/Icons/ic_chevron_right (= 10.1.0) + - MaterialComponents/private/Icons/ic_info (= 10.1.0) + - MaterialComponents/private/Icons/ic_radio_button_unchecked (= 10.1.0) + - MaterialComponents/private/Icons/ic_reorder (= 10.1.0) + - MaterialComponents/private/Icons/Base (10.1.0) + - MaterialComponents/private/Icons/ic_arrow_back (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_check (10.0.0): + - MaterialComponents/private/Icons/ic_check (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_check_circle (10.0.0): + - MaterialComponents/private/Icons/ic_check_circle (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_chevron_right (10.0.0): + - MaterialComponents/private/Icons/ic_chevron_right (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_info (10.0.0): + - MaterialComponents/private/Icons/ic_info (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_radio_button_unchecked (10.0.0): + - MaterialComponents/private/Icons/ic_radio_button_unchecked (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/Icons/ic_reorder (10.0.0): + - MaterialComponents/private/Icons/ic_reorder (10.1.0): - MaterialComponents/private/Icons/Base - - MaterialComponents/private/ThumbTrack (10.0.0): + - MaterialComponents/private/ThumbTrack (10.1.0): - MaterialComponents/Ink - MaterialComponents/private/Color - MaterialComponents/ShadowElevations - MaterialComponents/ShadowLayer - - MaterialComponents/RobotoFontLoader (10.0.0): + - MaterialComponents/RobotoFontLoader (10.1.0): - MaterialComponents/FontDiskLoader - MaterialComponents/Typography - - MaterialComponents/ShadowElevations (10.0.0) - - MaterialComponents/ShadowLayer (10.0.0) - - MaterialComponents/Slider (10.0.0): + - MaterialComponents/ShadowElevations (10.1.0) + - MaterialComponents/ShadowLayer (10.1.0) + - MaterialComponents/Slider (10.1.0): - MaterialComponents/private/ThumbTrack - - MaterialComponents/SpritedAnimationView (10.0.0) - - MaterialComponents/Switch (10.0.0): + - MaterialComponents/SpritedAnimationView (10.1.0) + - MaterialComponents/Switch (10.1.0): - MaterialComponents/private/ThumbTrack - - MaterialComponents/Typography (10.0.0) + - MaterialComponents/Typography (10.1.0) DEPENDENCIES: - MaterialComponents (from `../../`) @@ -119,7 +119,7 @@ EXTERNAL SOURCES: :path: ../../ SPEC CHECKSUMS: - MaterialComponents: 9c573b7371abd74208fe05a1915f3f02f513a009 + MaterialComponents: 65ac94f1904a9ddd867b95c2f3c55222943fd4fa PODFILE CHECKSUM: b585ca32a2884e050823cc1f861e8b7246f7dcc1 From ca997b82c1ca6f0e97b9da74a57b3acab5ec9aaf Mon Sep 17 00:00:00 2001 From: randallli Date: Wed, 8 Jun 2016 13:26:45 -0400 Subject: [PATCH 28/28] fixed copy edit nit on change log --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb4886f1209..fec197d0c59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,13 +42,13 @@ Added *NSCopying*. #### Changes -* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) +* [Updated examples and readme to use new swift selector syntax.](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) ### Buttons #### Changes -* [updated examples and readme to use new swift selector syntax](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) +* [Updated examples and readme to use new swift selector syntax.](https://github.com/google/material-components-ios/commit/25ea19e76a7b4d7baf9420639972127022c27602) (Eric Li) ### Collections