Repository: facebookarchive/Shimmer Branch: master Commit: a7eba1765263 Files: 36 Total size: 85.5 KB Directory structure: gitextract_nu9a22ug/ ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Examples/ │ ├── Examples.xcodeproj/ │ │ ├── project.pbxproj │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Logo-iOS.xcscheme │ ├── LICENSE │ └── Logo-iOS/ │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj/ │ │ ├── Main_iPad.storyboard │ │ └── Main_iPhone.storyboard │ ├── Images.xcassets/ │ │ ├── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── LaunchImage.launchimage/ │ │ │ └── Contents.json │ │ └── Wallpaper.imageset/ │ │ └── Contents.json │ ├── Logo-iOS-Info.plist │ ├── Logo-iOS-Prefix.pch │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj/ │ │ └── InfoPlist.strings │ └── main.m ├── FBShimmering/ │ ├── FBShimmering-Prefix.pch │ ├── FBShimmering.h │ ├── FBShimmeringLayer.h │ ├── FBShimmeringLayer.m │ ├── FBShimmeringView.h │ └── FBShimmeringView.m ├── FBShimmering.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ ├── FBShimmering.xcscheme │ └── Framework.xcscheme ├── FBShimmering.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── Framework/ │ ├── Info.plist │ └── Shimmer.h ├── LICENSE ├── README.md └── Shimmer.podspec ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store *.pbxuser *.perspective *.perspectivev3 *.mode1v3 *.mode2v3 *.xcodeproj/xcuserdata/*.xcuserdatad *.xccheckout *.xcuserdatad build/ Pods ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Code of Conduct Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.fb.com/codeofconduct) so that you can understand what actions will and will not be tolerated. ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing We want to make contributing to Shimmer as easy and transparent as possible. If you run into problems, please open an issue. We also actively welcome pull requests. ## Pull Requests 1. Fork the repo and create your branch from `master`. 2. If you've added code that should be tested, add tests 3. If you've changed APIs, update the documentation. 4. Ensure the test suite passes. 5. Make sure your code lints. 6. If you haven't already, complete the Contributor License Agreement ("CLA"). ## Contributor License Agreement ("CLA") In order to accept your pull request, we need you to submit a CLA. You only need to do this once to work on any of Facebook's open source projects. Complete your CLA here: ## Issues We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue. ## Coding Style * 2 spaces for indentation rather than tabs ## License By contributing to Shimmer you agree that your contributions will be licensed under its BSD license. ================================================ FILE: Examples/Examples.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 077ACA6E1CBD6B7200B3A708 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 077ACA6D1CBD6B7200B3A708 /* UIKit.framework */; }; EC45CACE18ADC7CE0063DD11 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC45CACD18ADC7CE0063DD11 /* Foundation.framework */; }; EC45CAD018ADC7CE0063DD11 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC45CACF18ADC7CE0063DD11 /* CoreGraphics.framework */; }; EC45CAD818ADC7CE0063DD11 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EC45CAD618ADC7CE0063DD11 /* InfoPlist.strings */; }; EC45CADA18ADC7CE0063DD11 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EC45CAD918ADC7CE0063DD11 /* main.m */; }; EC45CADE18ADC7CE0063DD11 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EC45CADD18ADC7CE0063DD11 /* AppDelegate.m */; }; EC45CAE118ADC7CE0063DD11 /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EC45CADF18ADC7CE0063DD11 /* Main_iPhone.storyboard */; }; EC45CAE418ADC7CE0063DD11 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EC45CAE218ADC7CE0063DD11 /* Main_iPad.storyboard */; }; EC45CAE718ADC7CE0063DD11 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EC45CAE618ADC7CE0063DD11 /* ViewController.m */; }; EC45CAE918ADC7CE0063DD11 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC45CAE818ADC7CE0063DD11 /* Images.xcassets */; }; EC45CB0418ADC7E80063DD11 /* libFBShimmering.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EC45CB0318ADC7E80063DD11 /* libFBShimmering.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 077ACA6D1CBD6B7200B3A708 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; EC45CACA18ADC7CE0063DD11 /* Logo-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Logo-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; EC45CACD18ADC7CE0063DD11 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; EC45CACF18ADC7CE0063DD11 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; EC45CAD518ADC7CE0063DD11 /* Logo-iOS-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Logo-iOS-Info.plist"; sourceTree = ""; }; EC45CAD718ADC7CE0063DD11 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; EC45CAD918ADC7CE0063DD11 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; EC45CADB18ADC7CE0063DD11 /* Logo-iOS-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Logo-iOS-Prefix.pch"; sourceTree = ""; }; EC45CADC18ADC7CE0063DD11 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; EC45CADD18ADC7CE0063DD11 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; EC45CAE018ADC7CE0063DD11 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; EC45CAE318ADC7CE0063DD11 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; }; EC45CAE518ADC7CE0063DD11 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; EC45CAE618ADC7CE0063DD11 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; EC45CAE818ADC7CE0063DD11 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; EC45CB0318ADC7E80063DD11 /* libFBShimmering.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libFBShimmering.a; path = "../../../Library/Developer/Xcode/DerivedData/FBShimmering-amnevtoymcgzwwazjmzbwvbeduoi/Build/Products/Debug-iphoneos/libFBShimmering.a"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ EC45CAC718ADC7CE0063DD11 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 077ACA6E1CBD6B7200B3A708 /* UIKit.framework in Frameworks */, EC45CB0418ADC7E80063DD11 /* libFBShimmering.a in Frameworks */, EC45CAD018ADC7CE0063DD11 /* CoreGraphics.framework in Frameworks */, EC45CACE18ADC7CE0063DD11 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ EC45CABF18ADC7920063DD11 = { isa = PBXGroup; children = ( ECC5761518ADEDFC00C2BFB8 /* Logo */, EC45CACC18ADC7CE0063DD11 /* Frameworks */, EC45CACB18ADC7CE0063DD11 /* Products */, ); indentWidth = 2; sourceTree = ""; tabWidth = 2; }; EC45CACB18ADC7CE0063DD11 /* Products */ = { isa = PBXGroup; children = ( EC45CACA18ADC7CE0063DD11 /* Logo-iOS.app */, ); name = Products; sourceTree = ""; }; EC45CACC18ADC7CE0063DD11 /* Frameworks */ = { isa = PBXGroup; children = ( EC45CB0318ADC7E80063DD11 /* libFBShimmering.a */, EC45CACD18ADC7CE0063DD11 /* Foundation.framework */, EC45CACF18ADC7CE0063DD11 /* CoreGraphics.framework */, 077ACA6D1CBD6B7200B3A708 /* UIKit.framework */, ); name = Frameworks; sourceTree = ""; }; EC45CAD318ADC7CE0063DD11 /* Logo-iOS */ = { isa = PBXGroup; children = ( EC45CADC18ADC7CE0063DD11 /* AppDelegate.h */, EC45CADD18ADC7CE0063DD11 /* AppDelegate.m */, EC45CADF18ADC7CE0063DD11 /* Main_iPhone.storyboard */, EC45CAE218ADC7CE0063DD11 /* Main_iPad.storyboard */, EC45CAE518ADC7CE0063DD11 /* ViewController.h */, EC45CAE618ADC7CE0063DD11 /* ViewController.m */, EC45CAE818ADC7CE0063DD11 /* Images.xcassets */, EC45CAD418ADC7CE0063DD11 /* Supporting Files */, ); path = "Logo-iOS"; sourceTree = ""; }; EC45CAD418ADC7CE0063DD11 /* Supporting Files */ = { isa = PBXGroup; children = ( EC45CAD518ADC7CE0063DD11 /* Logo-iOS-Info.plist */, EC45CAD618ADC7CE0063DD11 /* InfoPlist.strings */, EC45CAD918ADC7CE0063DD11 /* main.m */, EC45CADB18ADC7CE0063DD11 /* Logo-iOS-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; }; ECC5761518ADEDFC00C2BFB8 /* Logo */ = { isa = PBXGroup; children = ( EC45CAD318ADC7CE0063DD11 /* Logo-iOS */, ); name = Logo; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ EC45CAC918ADC7CE0063DD11 /* Logo-iOS */ = { isa = PBXNativeTarget; buildConfigurationList = EC45CAFD18ADC7CE0063DD11 /* Build configuration list for PBXNativeTarget "Logo-iOS" */; buildPhases = ( EC45CAC618ADC7CE0063DD11 /* Sources */, EC45CAC718ADC7CE0063DD11 /* Frameworks */, EC45CAC818ADC7CE0063DD11 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "Logo-iOS"; productName = "Logo-iOS"; productReference = EC45CACA18ADC7CE0063DD11 /* Logo-iOS.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ EC45CAC018ADC7920063DD11 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0510; }; buildConfigurationList = EC45CAC318ADC7920063DD11 /* Build configuration list for PBXProject "Examples" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = EC45CABF18ADC7920063DD11; productRefGroup = EC45CACB18ADC7CE0063DD11 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( EC45CAC918ADC7CE0063DD11 /* Logo-iOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ EC45CAC818ADC7CE0063DD11 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( EC45CAE418ADC7CE0063DD11 /* Main_iPad.storyboard in Resources */, EC45CAE918ADC7CE0063DD11 /* Images.xcassets in Resources */, EC45CAE118ADC7CE0063DD11 /* Main_iPhone.storyboard in Resources */, EC45CAD818ADC7CE0063DD11 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ EC45CAC618ADC7CE0063DD11 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( EC45CAE718ADC7CE0063DD11 /* ViewController.m in Sources */, EC45CADE18ADC7CE0063DD11 /* AppDelegate.m in Sources */, EC45CADA18ADC7CE0063DD11 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ EC45CAD618ADC7CE0063DD11 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( EC45CAD718ADC7CE0063DD11 /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; EC45CADF18ADC7CE0063DD11 /* Main_iPhone.storyboard */ = { isa = PBXVariantGroup; children = ( EC45CAE018ADC7CE0063DD11 /* Base */, ); name = Main_iPhone.storyboard; sourceTree = ""; }; EC45CAE218ADC7CE0063DD11 /* Main_iPad.storyboard */ = { isa = PBXVariantGroup; children = ( EC45CAE318ADC7CE0063DD11 /* Base */, ); name = Main_iPad.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ EC45CAC418ADC7920063DD11 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { IPHONEOS_DEPLOYMENT_TARGET = 6.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; EC45CAC518ADC7920063DD11 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { IPHONEOS_DEPLOYMENT_TARGET = 6.0; SDKROOT = iphoneos; }; name = Release; }; EC45CAFE18ADC7CE0063DD11 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Logo-iOS/Logo-iOS-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = "Logo-iOS/Logo-iOS-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/FBShimmering-amnevtoymcgzwwazjmzbwvbeduoi/Build/Products/Debug-iphoneos", ); ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Debug; }; EC45CAFF18ADC7CE0063DD11 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Logo-iOS/Logo-iOS-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = "Logo-iOS/Logo-iOS-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/FBShimmering-amnevtoymcgzwwazjmzbwvbeduoi/Build/Products/Debug-iphoneos", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ EC45CAC318ADC7920063DD11 /* Build configuration list for PBXProject "Examples" */ = { isa = XCConfigurationList; buildConfigurations = ( EC45CAC418ADC7920063DD11 /* Debug */, EC45CAC518ADC7920063DD11 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; EC45CAFD18ADC7CE0063DD11 /* Build configuration list for PBXNativeTarget "Logo-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( EC45CAFE18ADC7CE0063DD11 /* Debug */, EC45CAFF18ADC7CE0063DD11 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = EC45CAC018ADC7920063DD11 /* Project object */; } ================================================ FILE: Examples/Examples.xcodeproj/xcshareddata/xcschemes/Logo-iOS.xcscheme ================================================ ================================================ FILE: Examples/LICENSE ================================================ This file provided by Facebook is for non-commercial testing and evaluation purposes only. Facebook reserves all rights not expressly granted. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Examples/Logo-iOS/AppDelegate.h ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: Examples/Logo-iOS/AppDelegate.m ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import "AppDelegate.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return YES; } @end ================================================ FILE: Examples/Logo-iOS/Base.lproj/Main_iPad.storyboard ================================================ ================================================ FILE: Examples/Logo-iOS/Base.lproj/Main_iPhone.storyboard ================================================ ================================================ FILE: Examples/Logo-iOS/Images.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Logo-iOS/Images.xcassets/LaunchImage.launchimage/Contents.json ================================================ { "images" : [ { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "iphone", "subtype" : "retina4", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Logo-iOS/Images.xcassets/Wallpaper.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x", "filename" : "1800126_10152272440319357_261758585_o.png" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Logo-iOS/Logo-iOS-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier com.facebook.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 LSRequiresIPhoneOS UIMainStoryboardFile Main_iPhone UIMainStoryboardFile~ipad Main_iPad UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIStatusBarHidden UIStatusBarStyle UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: Examples/Logo-iOS/Logo-iOS-Prefix.pch ================================================ // // Prefix header // // The contents of this file are implicitly included at the beginning of every source file. // #import #ifndef __IPHONE_5_0 #warning "This project uses features only available in iOS SDK 5.0 and later." #endif #ifdef __OBJC__ #import #import #endif ================================================ FILE: Examples/Logo-iOS/ViewController.h ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import @interface ViewController : UIViewController @end ================================================ FILE: Examples/Logo-iOS/ViewController.m ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import "ViewController.h" #import @interface ViewController () @end @implementation ViewController { UIImageView *_wallpaperView; FBShimmeringView *_shimmeringView; UILabel *_logoLabel; UILabel *_valueLabel; CGFloat _panStartValue; BOOL _panVertical; } - (BOOL)prefersStatusBarHidden { return YES; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor]; _wallpaperView = [[UIImageView alloc] initWithFrame:self.view.bounds]; _wallpaperView.image = [UIImage imageNamed:@"Wallpaper"]; _wallpaperView.contentMode = UIViewContentModeScaleAspectFill; [self.view addSubview:_wallpaperView]; CGRect valueFrame = self.view.bounds; valueFrame.size.height = valueFrame.size.height * 0.25; _valueLabel = [[UILabel alloc] initWithFrame:valueFrame]; _valueLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight" size:32.0]; _valueLabel.textColor = [UIColor whiteColor]; _valueLabel.textAlignment = NSTextAlignmentCenter; _valueLabel.numberOfLines = 0; _valueLabel.alpha = 0.0; _valueLabel.backgroundColor = [UIColor clearColor]; [self.view addSubview:_valueLabel]; _shimmeringView = [[FBShimmeringView alloc] init]; _shimmeringView.shimmering = YES; _shimmeringView.shimmeringBeginFadeDuration = 0.3; _shimmeringView.shimmeringOpacity = 0.3; [self.view addSubview:_shimmeringView]; _logoLabel = [[UILabel alloc] initWithFrame:_shimmeringView.bounds]; _logoLabel.text = @"Shimmer"; _logoLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight" size:60.0]; _logoLabel.textColor = [UIColor whiteColor]; _logoLabel.textAlignment = NSTextAlignmentCenter; _logoLabel.backgroundColor = [UIColor clearColor]; _shimmeringView.contentView = _logoLabel; UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_tapped:)]; [self.view addGestureRecognizer:tapRecognizer]; UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(_panned:)]; [self.view addGestureRecognizer:panRecognizer]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; CGRect shimmeringFrame = self.view.bounds; shimmeringFrame.origin.y = shimmeringFrame.size.height * 0.68; shimmeringFrame.size.height = shimmeringFrame.size.height * 0.32; _shimmeringView.frame = shimmeringFrame; } - (void)_tapped:(UITapGestureRecognizer *)tapRecognizer { _shimmeringView.shimmering = !_shimmeringView.shimmering; } - (void)_panned:(UIPanGestureRecognizer *)panRecognizer { CGPoint translation = [panRecognizer translationInView:self.view]; CGPoint velocity = [panRecognizer velocityInView:self.view]; if (panRecognizer.state == UIGestureRecognizerStateBegan) { #if CGFLOAT_IS_DOUBLE _panVertical = (fabs(velocity.y) > fabs(velocity.x)); #else _panVertical = (fabsf(velocity.y) > fabsf(velocity.x)); #endif if (_panVertical) { _panStartValue = _shimmeringView.shimmeringSpeed; } else { _panStartValue = _shimmeringView.shimmeringOpacity; } [self _animateValueLabelVisible:YES]; } else if (panRecognizer.state == UIGestureRecognizerStateChanged) { CGFloat directional = (_panVertical ? translation.y : translation.x); CGFloat possible = (_panVertical ? self.view.bounds.size.height : self.view.bounds.size.width); CGFloat progress = (directional / possible); if (_panVertical) { _shimmeringView.shimmeringSpeed = fmaxf(0.0, fminf(1000.0, _panStartValue + progress * 200.0)); _valueLabel.text = [NSString stringWithFormat:@"Speed\n%.1f", _shimmeringView.shimmeringSpeed]; } else { _shimmeringView.shimmeringOpacity = fmaxf(0.0, fminf(1.0, _panStartValue + progress * 0.5)); _valueLabel.text = [NSString stringWithFormat:@"Opacity\n%.2f", _shimmeringView.shimmeringOpacity]; } } else if (panRecognizer.state == UIGestureRecognizerStateEnded || panRecognizer.state == UIGestureRecognizerStateCancelled) { [self _animateValueLabelVisible:NO]; } } - (void)_animateValueLabelVisible:(BOOL)visible { UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; void (^animations)() = ^{ _valueLabel.alpha = (visible ? 1.0 : 0.0); }; [UIView animateWithDuration:0.5 delay:0.0 options:options animations:animations completion:NULL]; } @end ================================================ FILE: Examples/Logo-iOS/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: Examples/Logo-iOS/main.m ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: FBShimmering/FBShimmering-Prefix.pch ================================================ // // Prefix header // // The contents of this file are implicitly included at the beginning of every source file. // #ifdef __OBJC__ #import #endif ================================================ FILE: FBShimmering/FBShimmering.h ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import #import typedef NS_ENUM(NSInteger, FBShimmerDirection) { //! Shimmer animation goes from left to right FBShimmerDirectionRight, //! Shimmer animation goes from right to left FBShimmerDirectionLeft, //! Shimmer animation goes from below to above FBShimmerDirectionUp, //! Shimmer animation goes from above to below FBShimmerDirectionDown, }; static const float FBShimmerDefaultBeginTime = CGFLOAT_MAX; @protocol FBShimmering //! @abstract Set this to YES to start shimming and NO to stop. Defaults to NO. @property (assign, nonatomic, readwrite, getter = isShimmering) BOOL shimmering; //! @abstract The time interval between shimmerings in seconds. Defaults to 0.4. @property (assign, nonatomic, readwrite) CFTimeInterval shimmeringPauseDuration; //! @abstract The opacity of the content while it is shimmering. Defaults to 0.5. @property (assign, nonatomic, readwrite) CGFloat shimmeringAnimationOpacity; //! @abstract The opacity of the content before it is shimmering. Defaults to 1.0. @property (assign, nonatomic, readwrite) CGFloat shimmeringOpacity; //! @abstract The speed of shimmering, in points per second. Defaults to 230. @property (assign, nonatomic, readwrite) CGFloat shimmeringSpeed; //! @abstract The highlight length of shimmering. Range of [0,1], defaults to 1.0. @property (assign, nonatomic, readwrite) CGFloat shimmeringHighlightLength; //! @abstract Same as "shimmeringHighlightLength", just for downward compatibility. @deprecated @property (assign, nonatomic, readwrite, getter = shimmeringHighlightLength, setter = setShimmeringHighlightLength:) CGFloat shimmeringHighlightWidth DEPRECATED_MSG_ATTRIBUTE("Use shimmeringHighlightLength"); //! @abstract The direction of shimmering animation. Defaults to FBShimmerDirectionRight. @property (assign, nonatomic, readwrite) FBShimmerDirection shimmeringDirection; //! @abstract The duration of the fade used when shimmer begins. Defaults to 0.1. @property (assign, nonatomic, readwrite) CFTimeInterval shimmeringBeginFadeDuration; //! @abstract The duration of the fade used when shimmer ends. Defaults to 0.3. @property (assign, nonatomic, readwrite) CFTimeInterval shimmeringEndFadeDuration; /** @abstract The absolute CoreAnimation media time when the shimmer will fade in. @discussion Only valid after setting {@ref shimmering} to NO. */ @property (assign, nonatomic, readonly) CFTimeInterval shimmeringFadeTime; /** @abstract The absolute CoreAnimation media time when the shimmer will begin. @discussion Only valid after setting {@ref shimmering} to YES. */ @property (assign, nonatomic) CFTimeInterval shimmeringBeginTime; @end ================================================ FILE: FBShimmering/FBShimmeringLayer.h ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import #import "FBShimmering.h" /** @abstract Lightweight, generic shimmering layer. */ @interface FBShimmeringLayer : CALayer //! @abstract The content layer to be shimmered. @property (strong, nonatomic) CALayer *contentLayer; @end ================================================ FILE: FBShimmering/FBShimmeringLayer.m ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import "FBShimmeringLayer.h" #import #import #import #import #import #if !__has_feature(objc_arc) #error This file must be compiled with ARC. Convert your project to ARC or specify the -fobjc-arc flag. #endif #if TARGET_IPHONE_SIMULATOR UIKIT_EXTERN float UIAnimationDragCoefficient(void); // UIKit private drag coeffient, use judiciously #endif static CGFloat FBShimmeringLayerDragCoefficient(void) { #if TARGET_IPHONE_SIMULATOR return UIAnimationDragCoefficient(); #else return 1.0; #endif } static void FBShimmeringLayerAnimationApplyDragCoefficient(CAAnimation *animation) { CGFloat k = FBShimmeringLayerDragCoefficient(); if (k != 0 && k != 1) { animation.speed = 1 / k; } } // animations keys static NSString *const kFBShimmerSlideAnimationKey = @"slide"; static NSString *const kFBFadeAnimationKey = @"fade"; static NSString *const kFBEndFadeAnimationKey = @"fade-end"; static CABasicAnimation *fade_animation(CALayer *layer, CGFloat opacity, CFTimeInterval duration) { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.fromValue = @([(layer.presentationLayer ?: layer) opacity]); animation.toValue = @(opacity); animation.fillMode = kCAFillModeBoth; animation.removedOnCompletion = NO; animation.duration = duration; FBShimmeringLayerAnimationApplyDragCoefficient(animation); return animation; } static CABasicAnimation *shimmer_slide_animation(CFTimeInterval duration, FBShimmerDirection direction) { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; animation.toValue = [NSValue valueWithCGPoint:CGPointZero]; animation.duration = duration; animation.repeatCount = HUGE_VALF; FBShimmeringLayerAnimationApplyDragCoefficient(animation); if (direction == FBShimmerDirectionLeft || direction == FBShimmerDirectionUp) { animation.speed = -fabsf(animation.speed); } return animation; } // take a shimmer slide animation and turns into repeating static CAAnimation *shimmer_slide_repeat(CAAnimation *a, CFTimeInterval duration, FBShimmerDirection direction) { CAAnimation *anim = [a copy]; anim.repeatCount = HUGE_VALF; anim.duration = duration; anim.speed = (direction == FBShimmerDirectionRight || direction == FBShimmerDirectionDown) ? fabsf(anim.speed) : -fabsf(anim.speed); return anim; } // take a shimmer slide animation and turns into finish static CAAnimation *shimmer_slide_finish(CAAnimation *a) { CAAnimation *anim = [a copy]; anim.repeatCount = 0; return anim; } @interface FBShimmeringMaskLayer : CAGradientLayer @property (readonly, nonatomic) CALayer *fadeLayer; @end @implementation FBShimmeringMaskLayer - (instancetype)init { self = [super init]; if (nil != self) { _fadeLayer = [[CALayer alloc] init]; _fadeLayer.backgroundColor = [UIColor whiteColor].CGColor; [self addSublayer:_fadeLayer]; } return self; } - (void)layoutSublayers { [super layoutSublayers]; CGRect r = self.bounds; _fadeLayer.bounds = r; _fadeLayer.position = CGPointMake(CGRectGetMidX(r), CGRectGetMidY(r)); } @end @interface FBShimmeringLayer () #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 // iOS 10 SDK has CALayerDelegate and CAAnimationDelegate as proper protocols. #endif @property (strong, nonatomic) FBShimmeringMaskLayer *maskLayer; @end @implementation FBShimmeringLayer { CALayer *_contentLayer; FBShimmeringMaskLayer *_maskLayer; } #pragma mark - Lifecycle @synthesize shimmering = _shimmering; @synthesize shimmeringPauseDuration = _shimmeringPauseDuration; @synthesize shimmeringAnimationOpacity = _shimmeringAnimationOpacity; @synthesize shimmeringOpacity = _shimmeringOpacity; @synthesize shimmeringSpeed = _shimmeringSpeed; @synthesize shimmeringHighlightLength = _shimmeringHighlightLength; @synthesize shimmeringDirection = _shimmeringDirection; @synthesize shimmeringFadeTime = _shimmeringFadeTime; @synthesize shimmeringBeginFadeDuration = _shimmeringBeginFadeDuration; @synthesize shimmeringEndFadeDuration = _shimmeringEndFadeDuration; @synthesize shimmeringBeginTime = _shimmeringBeginTime; @dynamic shimmeringHighlightWidth; - (instancetype)init { self = [super init]; if (nil != self) { // default configuration _shimmeringPauseDuration = 0.4; _shimmeringSpeed = 230.0; _shimmeringHighlightLength = 1.0; _shimmeringAnimationOpacity = 0.5; _shimmeringOpacity = 1.0; _shimmeringDirection = FBShimmerDirectionRight; _shimmeringBeginFadeDuration = 0.1; _shimmeringEndFadeDuration = 0.3; _shimmeringBeginTime = FBShimmerDefaultBeginTime; } return self; } #pragma mark - Properties - (void)setContentLayer:(CALayer *)contentLayer { // reset mask self.maskLayer = nil; // note content layer and add for display _contentLayer = contentLayer; self.sublayers = contentLayer ? @[contentLayer] : nil; // update shimmering animation [self _updateShimmering]; } - (void)setShimmering:(BOOL)shimmering { if (shimmering != _shimmering) { _shimmering = shimmering; [self _updateShimmering]; } } - (void)setShimmeringSpeed:(CGFloat)speed { if (speed != _shimmeringSpeed) { _shimmeringSpeed = speed; [self _updateShimmering]; } } - (void)setShimmeringHighlightLength:(CGFloat)length { if (length != _shimmeringHighlightLength) { _shimmeringHighlightLength = length; [self _updateShimmering]; } } - (void)setShimmeringDirection:(FBShimmerDirection)direction { if (direction != _shimmeringDirection) { _shimmeringDirection = direction; [self _updateShimmering]; } } - (void)setShimmeringPauseDuration:(CFTimeInterval)duration { if (duration != _shimmeringPauseDuration) { _shimmeringPauseDuration = duration; [self _updateShimmering]; } } - (void)setShimmeringAnimationOpacity:(CGFloat)shimmeringAnimationOpacity { if (shimmeringAnimationOpacity != _shimmeringAnimationOpacity) { _shimmeringAnimationOpacity = shimmeringAnimationOpacity; [self _updateMaskColors]; } } - (void)setShimmeringOpacity:(CGFloat)shimmeringOpacity { if (shimmeringOpacity != _shimmeringOpacity) { _shimmeringOpacity = shimmeringOpacity; [self _updateMaskColors]; } } - (void)setShimmeringBeginTime:(CFTimeInterval)beginTime { if (beginTime != _shimmeringBeginTime) { _shimmeringBeginTime = beginTime; [self _updateShimmering]; } } - (void)layoutSublayers { [super layoutSublayers]; CGRect r = self.bounds; _contentLayer.anchorPoint = CGPointMake(0.5, 0.5); _contentLayer.bounds = r; _contentLayer.position = CGPointMake(CGRectGetMidX(r), CGRectGetMidY(r)); if (nil != _maskLayer) { [self _updateMaskLayout]; } } - (void)setBounds:(CGRect)bounds { CGRect oldBounds = self.bounds; [super setBounds:bounds]; if (!CGRectEqualToRect(oldBounds, bounds)) { [self _updateShimmering]; } } #pragma mark - Internal - (void)_clearMask { if (nil == _maskLayer) { return; } BOOL disableActions = [CATransaction disableActions]; [CATransaction setDisableActions:YES]; self.maskLayer = nil; _contentLayer.mask = nil; [CATransaction setDisableActions:disableActions]; } - (void)_createMaskIfNeeded { if (_shimmering && !_maskLayer) { _maskLayer = [FBShimmeringMaskLayer layer]; _maskLayer.delegate = self; _contentLayer.mask = _maskLayer; [self _updateMaskColors]; [self _updateMaskLayout]; } } - (void)_updateMaskColors { if (nil == _maskLayer) { return; } // We create a gradient to be used as a mask. // In a mask, the colors do not matter, it's the alpha that decides the degree of masking. UIColor *maskedColor = [UIColor colorWithWhite:1.0 alpha:_shimmeringOpacity]; UIColor *unmaskedColor = [UIColor colorWithWhite:1.0 alpha:_shimmeringAnimationOpacity]; // Create a gradient from masked to unmasked to masked. _maskLayer.colors = @[(__bridge id)maskedColor.CGColor, (__bridge id)unmaskedColor.CGColor, (__bridge id)maskedColor.CGColor]; } - (void)_updateMaskLayout { // Everything outside the mask layer is hidden, so we need to create a mask long enough for the shimmered layer to be always covered by the mask. CGFloat length = 0.0f; if (_shimmeringDirection == FBShimmerDirectionDown || _shimmeringDirection == FBShimmerDirectionUp) { length = CGRectGetHeight(_contentLayer.bounds); } else { length = CGRectGetWidth(_contentLayer.bounds); } if (0 == length) { return; } // extra distance for the gradient to travel during the pause. CGFloat extraDistance = length + _shimmeringSpeed * _shimmeringPauseDuration; // compute how far the shimmering goes CGFloat fullShimmerLength = length * 3.0f + extraDistance; CGFloat travelDistance = length * 2.0f + extraDistance; // position the gradient for the desired width CGFloat highlightOutsideLength = (1.0 - _shimmeringHighlightLength) / 2.0; _maskLayer.locations = @[@(highlightOutsideLength), @(0.5), @(1.0 - highlightOutsideLength)]; CGFloat startPoint = (length + extraDistance) / fullShimmerLength; CGFloat endPoint = travelDistance / fullShimmerLength; // position for the start of the animation _maskLayer.anchorPoint = CGPointZero; if (_shimmeringDirection == FBShimmerDirectionDown || _shimmeringDirection == FBShimmerDirectionUp) { _maskLayer.startPoint = CGPointMake(0.0, startPoint); _maskLayer.endPoint = CGPointMake(0.0, endPoint); _maskLayer.position = CGPointMake(0.0, -travelDistance); _maskLayer.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_contentLayer.bounds), fullShimmerLength); } else { _maskLayer.startPoint = CGPointMake(startPoint, 0.0); _maskLayer.endPoint = CGPointMake(endPoint, 0.0); _maskLayer.position = CGPointMake(-travelDistance, 0.0); _maskLayer.bounds = CGRectMake(0.0, 0.0, fullShimmerLength, CGRectGetHeight(_contentLayer.bounds)); } } - (void)_updateShimmering { // create mask if needed [self _createMaskIfNeeded]; // if not shimmering and no mask, noop if (!_shimmering && !_maskLayer) { return; } // ensure layout [self layoutIfNeeded]; BOOL disableActions = [CATransaction disableActions]; if (!_shimmering) { if (disableActions) { // simply remove mask [self _clearMask]; } else { // end slide CFTimeInterval slideEndTime = 0; CAAnimation *slideAnimation = [_maskLayer animationForKey:kFBShimmerSlideAnimationKey]; if (slideAnimation != nil) { // determine total time sliding CFTimeInterval now = CACurrentMediaTime(); CFTimeInterval slideTotalDuration = now - slideAnimation.beginTime; // determine time offset into current slide CFTimeInterval slideTimeOffset = fmod(slideTotalDuration, slideAnimation.duration); // transition to non-repeating slide CAAnimation *finishAnimation = shimmer_slide_finish(slideAnimation); // adjust begin time to now - offset finishAnimation.beginTime = now - slideTimeOffset; // note slide end time and begin slideEndTime = finishAnimation.beginTime + slideAnimation.duration; [_maskLayer addAnimation:finishAnimation forKey:kFBShimmerSlideAnimationKey]; } // fade in text at slideEndTime CABasicAnimation *fadeInAnimation = fade_animation(_maskLayer.fadeLayer, 1.0, _shimmeringEndFadeDuration); fadeInAnimation.delegate = self; [fadeInAnimation setValue:@YES forKey:kFBEndFadeAnimationKey]; fadeInAnimation.beginTime = slideEndTime; [_maskLayer.fadeLayer addAnimation:fadeInAnimation forKey:kFBFadeAnimationKey]; // expose end time for synchronization _shimmeringFadeTime = slideEndTime; } } else { // fade out text, optionally animated CABasicAnimation *fadeOutAnimation = nil; if (_shimmeringBeginFadeDuration > 0.0 && !disableActions) { fadeOutAnimation = fade_animation(_maskLayer.fadeLayer, 0.0, _shimmeringBeginFadeDuration); [_maskLayer.fadeLayer addAnimation:fadeOutAnimation forKey:kFBFadeAnimationKey]; } else { BOOL innerDisableActions = [CATransaction disableActions]; [CATransaction setDisableActions:YES]; _maskLayer.fadeLayer.opacity = 0.0; [_maskLayer.fadeLayer removeAllAnimations]; [CATransaction setDisableActions:innerDisableActions]; } // begin slide animation CAAnimation *slideAnimation = [_maskLayer animationForKey:kFBShimmerSlideAnimationKey]; // compute shimmer duration CGFloat length = 0.0f; if (_shimmeringDirection == FBShimmerDirectionDown || _shimmeringDirection == FBShimmerDirectionUp) { length = CGRectGetHeight(_contentLayer.bounds); } else { length = CGRectGetWidth(_contentLayer.bounds); } CFTimeInterval animationDuration = (length / _shimmeringSpeed) + _shimmeringPauseDuration; if (slideAnimation != nil) { // ensure existing slide animation repeats [_maskLayer addAnimation:shimmer_slide_repeat(slideAnimation, animationDuration, _shimmeringDirection) forKey:kFBShimmerSlideAnimationKey]; } else { // add slide animation slideAnimation = shimmer_slide_animation(animationDuration, _shimmeringDirection); slideAnimation.fillMode = kCAFillModeForwards; slideAnimation.removedOnCompletion = NO; if (_shimmeringBeginTime == FBShimmerDefaultBeginTime) { _shimmeringBeginTime = CACurrentMediaTime() + fadeOutAnimation.duration; } slideAnimation.beginTime = _shimmeringBeginTime; [_maskLayer addAnimation:slideAnimation forKey:kFBShimmerSlideAnimationKey]; } } } #pragma mark - CALayerDelegate - (id)actionForLayer:(CALayer *)layer forKey:(NSString *)event { // no associated actions return (id)kCFNull; } #pragma mark - CAAnimationDelegate - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if (flag && [[anim valueForKey:kFBEndFadeAnimationKey] boolValue]) { [_maskLayer.fadeLayer removeAnimationForKey:kFBFadeAnimationKey]; [self _clearMask]; } } @end ================================================ FILE: FBShimmering/FBShimmeringView.h ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import #import "FBShimmering.h" /** @abstract Lightweight, generic shimmering view. */ @interface FBShimmeringView : UIView //! @abstract The content view to be shimmered. @property (strong, nonatomic) UIView *contentView; @end ================================================ FILE: FBShimmering/FBShimmeringView.m ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import "FBShimmeringView.h" #import "FBShimmeringLayer.h" #if !__has_feature(objc_arc) #error This file must be compiled with ARC. Convert your project to ARC or specify the -fobjc-arc flag. #endif @implementation FBShimmeringView + (Class)layerClass { return [FBShimmeringLayer class]; } #define __layer ((FBShimmeringLayer *)self.layer) #define LAYER_ACCESSOR(accessor, ctype) \ - (ctype)accessor { \ return [__layer accessor]; \ } #define LAYER_MUTATOR(mutator, ctype) \ - (void)mutator (ctype)value { \ [__layer mutator value]; \ } #define LAYER_RW_PROPERTY(accessor, mutator, ctype) \ LAYER_ACCESSOR (accessor, ctype) \ LAYER_MUTATOR (mutator, ctype) LAYER_RW_PROPERTY(isShimmering, setShimmering:, BOOL) LAYER_RW_PROPERTY(shimmeringPauseDuration, setShimmeringPauseDuration:, CFTimeInterval) LAYER_RW_PROPERTY(shimmeringAnimationOpacity, setShimmeringAnimationOpacity:, CGFloat) LAYER_RW_PROPERTY(shimmeringOpacity, setShimmeringOpacity:, CGFloat) LAYER_RW_PROPERTY(shimmeringSpeed, setShimmeringSpeed:, CGFloat) LAYER_RW_PROPERTY(shimmeringHighlightLength, setShimmeringHighlightLength:, CGFloat) LAYER_RW_PROPERTY(shimmeringDirection, setShimmeringDirection:, FBShimmerDirection) LAYER_ACCESSOR(shimmeringFadeTime, CFTimeInterval) LAYER_RW_PROPERTY(shimmeringBeginFadeDuration, setShimmeringBeginFadeDuration:, CFTimeInterval) LAYER_RW_PROPERTY(shimmeringEndFadeDuration, setShimmeringEndFadeDuration:, CFTimeInterval) LAYER_RW_PROPERTY(shimmeringBeginTime, setShimmeringBeginTime:, CFTimeInterval) - (void)setContentView:(UIView *)contentView { if (contentView != _contentView) { _contentView = contentView; [self addSubview:contentView]; __layer.contentLayer = contentView.layer; } } - (void)layoutSubviews { // Autolayout requires these to be set on the UIView, not the CALayer. // Do this *before* the layer has a chance to set the properties, as the // setters would be ignored (even for autolayout) if set to the same value. _contentView.bounds = self.bounds; _contentView.center = self.center; [super layoutSubviews]; } @end ================================================ FILE: FBShimmering.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 077ACA6A1CBD6B4300B3A708 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 077ACA691CBD6B4300B3A708 /* UIKit.framework */; }; 077ACA6C1CBD6B5800B3A708 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 077ACA6B1CBD6B5800B3A708 /* CoreGraphics.framework */; }; 1899D26B18BD1CFB0035A1B0 /* FBShimmeringView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1899D26718BD1CFB0035A1B0 /* FBShimmeringView.m */; }; 1899D26C18BD1CFB0035A1B0 /* FBShimmeringLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1899D26918BD1CFB0035A1B0 /* FBShimmeringLayer.m */; }; 1899D27418BD201B0035A1B0 /* FBShimmering.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1899D26D18BD1D070035A1B0 /* FBShimmering.h */; }; 1899D27518BD201B0035A1B0 /* FBShimmeringView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1899D26818BD1CFB0035A1B0 /* FBShimmeringView.h */; }; 1899D27618BD201B0035A1B0 /* FBShimmeringLayer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1899D26A18BD1CFB0035A1B0 /* FBShimmeringLayer.h */; }; A1C8E0BF1E13C0C9002D6069 /* Shimmer.h in Headers */ = {isa = PBXBuildFile; fileRef = A1C8E0BD1E13C0C9002D6069 /* Shimmer.h */; settings = {ATTRIBUTES = (Public, ); }; }; A1C8E0C31E13C0D3002D6069 /* FBShimmering.h in Headers */ = {isa = PBXBuildFile; fileRef = 1899D26D18BD1D070035A1B0 /* FBShimmering.h */; settings = {ATTRIBUTES = (Public, ); }; }; A1C8E0C41E13C0D3002D6069 /* FBShimmeringView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1899D26818BD1CFB0035A1B0 /* FBShimmeringView.h */; settings = {ATTRIBUTES = (Public, ); }; }; A1C8E0C51E13C0D3002D6069 /* FBShimmeringLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1899D26A18BD1CFB0035A1B0 /* FBShimmeringLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; A1C8E0C61E13C0D8002D6069 /* FBShimmeringView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1899D26718BD1CFB0035A1B0 /* FBShimmeringView.m */; }; A1C8E0C71E13C0D8002D6069 /* FBShimmeringLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1899D26918BD1CFB0035A1B0 /* FBShimmeringLayer.m */; }; ECEA610218A49C620064AFF4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECEA610118A49C620064AFF4 /* Foundation.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ ECEA60FC18A49C620064AFF4 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = "$(PRODUCT_NAME)Headers"; dstSubfolderSpec = 16; files = ( 1899D27418BD201B0035A1B0 /* FBShimmering.h in CopyFiles */, 1899D27518BD201B0035A1B0 /* FBShimmeringView.h in CopyFiles */, 1899D27618BD201B0035A1B0 /* FBShimmeringLayer.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 077ACA691CBD6B4300B3A708 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 077ACA6B1CBD6B5800B3A708 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 1899D26718BD1CFB0035A1B0 /* FBShimmeringView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBShimmeringView.m; sourceTree = ""; }; 1899D26818BD1CFB0035A1B0 /* FBShimmeringView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBShimmeringView.h; sourceTree = ""; }; 1899D26918BD1CFB0035A1B0 /* FBShimmeringLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBShimmeringLayer.m; sourceTree = ""; }; 1899D26A18BD1CFB0035A1B0 /* FBShimmeringLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBShimmeringLayer.h; sourceTree = ""; }; 1899D26D18BD1D070035A1B0 /* FBShimmering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBShimmering.h; sourceTree = ""; }; A1C8E0BB1E13C0C9002D6069 /* Shimmer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Shimmer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A1C8E0BD1E13C0C9002D6069 /* Shimmer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shimmer.h; sourceTree = ""; }; A1C8E0BE1E13C0C9002D6069 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; EC8BB5B318A5A1EE00EB2793 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; EC8BB5B418A5A1F500EB2793 /* PATENTS */ = {isa = PBXFileReference; lastKnownFileType = text; path = PATENTS; sourceTree = ""; }; EC8BB5B518A5A30700EB2793 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = CONTRIBUTING.md; sourceTree = ""; }; EC8BB5B618A5A30F00EB2793 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; }; ECEA60FE18A49C620064AFF4 /* libFBShimmering.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFBShimmering.a; sourceTree = BUILT_PRODUCTS_DIR; }; ECEA610118A49C620064AFF4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; ECEA610518A49C620064AFF4 /* FBShimmering-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBShimmering-Prefix.pch"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ A1C8E0B71E13C0C9002D6069 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; ECEA60FB18A49C620064AFF4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 077ACA6C1CBD6B5800B3A708 /* CoreGraphics.framework in Frameworks */, 077ACA6A1CBD6B4300B3A708 /* UIKit.framework in Frameworks */, ECEA610218A49C620064AFF4 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ A1C8E0BC1E13C0C9002D6069 /* Framework */ = { isa = PBXGroup; children = ( A1C8E0BD1E13C0C9002D6069 /* Shimmer.h */, A1C8E0BE1E13C0C9002D6069 /* Info.plist */, ); path = Framework; sourceTree = ""; }; ECEA60F518A49C620064AFF4 = { isa = PBXGroup; children = ( EC8BB5B618A5A30F00EB2793 /* README.md */, EC8BB5B518A5A30700EB2793 /* CONTRIBUTING.md */, EC8BB5B318A5A1EE00EB2793 /* LICENSE */, EC8BB5B418A5A1F500EB2793 /* PATENTS */, ECEA610318A49C620064AFF4 /* FBShimmering */, A1C8E0BC1E13C0C9002D6069 /* Framework */, ECEA610018A49C620064AFF4 /* Frameworks */, ECEA60FF18A49C620064AFF4 /* Products */, ); indentWidth = 2; sourceTree = ""; tabWidth = 2; }; ECEA60FF18A49C620064AFF4 /* Products */ = { isa = PBXGroup; children = ( ECEA60FE18A49C620064AFF4 /* libFBShimmering.a */, A1C8E0BB1E13C0C9002D6069 /* Shimmer.framework */, ); name = Products; sourceTree = ""; }; ECEA610018A49C620064AFF4 /* Frameworks */ = { isa = PBXGroup; children = ( 077ACA6B1CBD6B5800B3A708 /* CoreGraphics.framework */, 077ACA691CBD6B4300B3A708 /* UIKit.framework */, ECEA610118A49C620064AFF4 /* Foundation.framework */, ); name = Frameworks; sourceTree = ""; }; ECEA610318A49C620064AFF4 /* FBShimmering */ = { isa = PBXGroup; children = ( 1899D26D18BD1D070035A1B0 /* FBShimmering.h */, 1899D26818BD1CFB0035A1B0 /* FBShimmeringView.h */, 1899D26718BD1CFB0035A1B0 /* FBShimmeringView.m */, 1899D26A18BD1CFB0035A1B0 /* FBShimmeringLayer.h */, 1899D26918BD1CFB0035A1B0 /* FBShimmeringLayer.m */, ECEA610418A49C620064AFF4 /* Supporting Files */, ); path = FBShimmering; sourceTree = ""; }; ECEA610418A49C620064AFF4 /* Supporting Files */ = { isa = PBXGroup; children = ( ECEA610518A49C620064AFF4 /* FBShimmering-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ A1C8E0B81E13C0C9002D6069 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( A1C8E0BF1E13C0C9002D6069 /* Shimmer.h in Headers */, A1C8E0C31E13C0D3002D6069 /* FBShimmering.h in Headers */, A1C8E0C41E13C0D3002D6069 /* FBShimmeringView.h in Headers */, A1C8E0C51E13C0D3002D6069 /* FBShimmeringLayer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ A1C8E0BA1E13C0C9002D6069 /* Shimmer */ = { isa = PBXNativeTarget; buildConfigurationList = A1C8E0C01E13C0C9002D6069 /* Build configuration list for PBXNativeTarget "Shimmer" */; buildPhases = ( A1C8E0B61E13C0C9002D6069 /* Sources */, A1C8E0B71E13C0C9002D6069 /* Frameworks */, A1C8E0B81E13C0C9002D6069 /* Headers */, A1C8E0B91E13C0C9002D6069 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = Shimmer; productName = Shimmer; productReference = A1C8E0BB1E13C0C9002D6069 /* Shimmer.framework */; productType = "com.apple.product-type.framework"; }; ECEA60FD18A49C620064AFF4 /* FBShimmering */ = { isa = PBXNativeTarget; buildConfigurationList = ECEA612118A49C620064AFF4 /* Build configuration list for PBXNativeTarget "FBShimmering" */; buildPhases = ( ECEA60FA18A49C620064AFF4 /* Sources */, ECEA60FB18A49C620064AFF4 /* Frameworks */, ECEA60FC18A49C620064AFF4 /* CopyFiles */, ECEA612718A49DDD0064AFF4 /* ShellScript */, ); buildRules = ( ); dependencies = ( ); name = FBShimmering; productName = FBShimmering; productReference = ECEA60FE18A49C620064AFF4 /* libFBShimmering.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ ECEA60F618A49C620064AFF4 /* Project object */ = { isa = PBXProject; attributes = { CLASSPREFIX = FB; LastUpgradeCheck = 0510; ORGANIZATIONNAME = Facebook; }; buildConfigurationList = ECEA60F918A49C620064AFF4 /* Build configuration list for PBXProject "FBShimmering" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = ECEA60F518A49C620064AFF4; productRefGroup = ECEA60FF18A49C620064AFF4 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( ECEA60FD18A49C620064AFF4 /* FBShimmering */, A1C8E0BA1E13C0C9002D6069 /* Shimmer */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ A1C8E0B91E13C0C9002D6069 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ ECEA612718A49DDD0064AFF4 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "set -e\n\nmkdir -p \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Versions/A/Headers\"\n\n# Link the \"Current\" version to \"A\"\n/bin/ln -sfh A \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Versions/Current\"\n/bin/ln -sfh Versions/Current/Headers \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Headers\"\n/bin/ln -sfh \"Versions/Current/${PRODUCT_NAME}\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}\"\n\n# The -a ensures that the headers maintain the source modification date so that we don't constantly\n# cause propagating rebuilds of files that import these headers.\n/bin/cp -a \"${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Versions/A/Headers\""; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ A1C8E0B61E13C0C9002D6069 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( A1C8E0C71E13C0D8002D6069 /* FBShimmeringLayer.m in Sources */, A1C8E0C61E13C0D8002D6069 /* FBShimmeringView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; ECEA60FA18A49C620064AFF4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 1899D26C18BD1CFB0035A1B0 /* FBShimmeringLayer.m in Sources */, 1899D26B18BD1CFB0035A1B0 /* FBShimmeringView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ A1C8E0C11E13C0C9002D6069 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = Framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Shimmer; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; A1C8E0C21E13C0C9002D6069 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = Framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Shimmer; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; ECEA611F18A49C620064AFF4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 6.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; ECEA612018A49C620064AFF4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 6.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; ECEA612218A49C620064AFF4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/FBShimmering.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "FBShimmering/FBShimmering-Prefix.pch"; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers"; SKIP_INSTALL = YES; STRIP_STYLE = "non-global"; }; name = Debug; }; ECEA612318A49C620064AFF4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/FBShimmering.dst; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "FBShimmering/FBShimmering-Prefix.pch"; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers"; SKIP_INSTALL = YES; STRIP_STYLE = "non-global"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ A1C8E0C01E13C0C9002D6069 /* Build configuration list for PBXNativeTarget "Shimmer" */ = { isa = XCConfigurationList; buildConfigurations = ( A1C8E0C11E13C0C9002D6069 /* Debug */, A1C8E0C21E13C0C9002D6069 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; ECEA60F918A49C620064AFF4 /* Build configuration list for PBXProject "FBShimmering" */ = { isa = XCConfigurationList; buildConfigurations = ( ECEA611F18A49C620064AFF4 /* Debug */, ECEA612018A49C620064AFF4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; ECEA612118A49C620064AFF4 /* Build configuration list for PBXNativeTarget "FBShimmering" */ = { isa = XCConfigurationList; buildConfigurations = ( ECEA612218A49C620064AFF4 /* Debug */, ECEA612318A49C620064AFF4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = ECEA60F618A49C620064AFF4 /* Project object */; } ================================================ FILE: FBShimmering.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: FBShimmering.xcodeproj/xcshareddata/xcschemes/FBShimmering.xcscheme ================================================ ================================================ FILE: FBShimmering.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme ================================================ ================================================ FILE: FBShimmering.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: FBShimmering.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: Framework/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: Framework/Shimmer.h ================================================ /** Copyright (c) 2014-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. */ #import #import #import ================================================ FILE: LICENSE ================================================ BSD License For Shimmer software Copyright (c) 2014, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ # Shimmer Shimmer is an easy way to add a shimmering effect to any view in your app. It's useful as an unobtrusive loading indicator. Shimmer was originally developed to show loading status in [Paper](http://facebook.com/paper). ![Shimmer](https://github.com/facebook/Shimmer/blob/master/shimmer.gif?raw=true) ## Usage To use Shimmer, create a `FBShimmeringView` or `FBShimmeringLayer` and add your content. To start shimmering, set the `shimmering` property to `YES`. An example of making a label shimmer: ```objective-c FBShimmeringView *shimmeringView = [[FBShimmeringView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:shimmeringView]; UILabel *loadingLabel = [[UILabel alloc] initWithFrame:shimmeringView.bounds]; loadingLabel.textAlignment = NSTextAlignmentCenter; loadingLabel.text = NSLocalizedString(@"Shimmer", nil); shimmeringView.contentView = loadingLabel; // Start shimmering. shimmeringView.shimmering = YES; ``` There's also an example project. In the example, you can swipe horizontally and vertically to try various shimmering parameters, or tap to start or stop shimmering. (To build the example locally, you'll need to open `FBShimmering.xcworkpace` rather than the `.xcodeproj`.) ## Installation There are two options: 1. Shimmer is available as `Shimmer` in [Cocoapods](http://cocoapods.org). 2. Manually add the files into your Xcode project. Slightly simpler, but updates are also manual. Shimmer requires iOS 6 or later. ## How it works Shimmer uses the `-[CALayer mask]` property to enable shimmering, similar to what's described in John Harper's 2009 WWDC talk (unfortunately no longer online). Shimmer uses CoreAnimation's timing features to smoothly transition "on-beat" when starting and stopping the shimmer. ## Other Platforms We have a version of Shimmer for Android, too! It's [also available on GitHub](https://github.com/facebook/shimmer-android). ## Contributing See the CONTRIBUTING file for how to help out. ## License Shimmer is BSD-licensed. ================================================ FILE: Shimmer.podspec ================================================ Pod::Spec.new do |spec| spec.name = 'Shimmer' spec.version = '1.0.2' spec.license = { :type => 'BSD' } spec.homepage = 'https://github.com/facebook/Shimmer' spec.authors = { 'Grant Paul' => 'shimmer@grantpaul.com', 'Kimon Tsinteris' => 'kimon@mac.com' } spec.summary = 'Simple shimmering effect.' spec.source = { :git => 'https://github.com/facebook/Shimmer.git', :tag => '1.0.2' } spec.source_files = 'FBShimmering/FBShimmering{,View,Layer}.{h,m}' spec.requires_arc = true spec.ios.deployment_target = '6.0' end