├── .swiftpm └── xcode │ └── xcshareddata │ └── xcschemes │ └── AnimatedTabBar.xcscheme ├── AnimatedTabBarExample ├── AnimatedTabBarExample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Example.xcscheme └── AnimatedTabBarExample │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── colorTab1.imageset │ │ ├── Contents.json │ │ └── colorTab1.pdf │ ├── colorTab1Bg.imageset │ │ ├── Contents.json │ │ └── colorTab1Bg.pdf │ ├── colorTab2.imageset │ │ ├── Contents.json │ │ └── colorTab2.pdf │ ├── colorTab2Bg.imageset │ │ ├── Contents.json │ │ └── colorTab2Bg.pdf │ ├── colorTab3.imageset │ │ ├── Contents.json │ │ └── colorTab3.pdf │ ├── colorTab3Bg.imageset │ │ ├── Contents.json │ │ └── colorTab3Bg.pdf │ ├── colorTab3Plus.imageset │ │ ├── Contents.json │ │ └── colorTab3Plus.pdf │ ├── colorTab4.imageset │ │ ├── Contents.json │ │ └── colorTab4.pdf │ ├── colorTab4Bg.imageset │ │ ├── Contents.json │ │ └── colorTab4Bg.pdf │ ├── colorTab5.imageset │ │ ├── Contents.json │ │ └── colorTab5.pdf │ ├── colorTab5Bg.imageset │ │ ├── Contents.json │ │ └── colorTab5Bg.pdf │ ├── tab1.imageset │ │ ├── Contents.json │ │ └── Icon.pdf │ ├── tab2.imageset │ │ ├── Contents.json │ │ └── Icon (1).pdf │ ├── tab3.imageset │ │ ├── Contents.json │ │ └── message_24.pdf │ ├── tab4.imageset │ │ ├── Contents.json │ │ └── Icon (2).pdf │ └── tab5.imageset │ │ ├── Contents.json │ │ └── Icon (3).pdf │ ├── ContentView.swift │ ├── ExampleApp.swift │ ├── ExampleColorButtons.swift │ ├── Info.plist │ ├── KeyframeWiggleButton.swift │ └── Utils.swift ├── LICENSE ├── Package.swift ├── README.md └── Sources ├── AnimatedTabBar.h └── AnimatedTabBar ├── AnimatedTabbar.swift ├── BezierPathLength.swift ├── ButtonsBarLayout.swift ├── GeometryEffects.swift ├── IndentableRect.swift ├── TabBarButtons ├── DropletButton.swift └── WiggleButton.swift └── Utils.swift /.swiftpm/xcode/xcshareddata/xcschemes/AnimatedTabBar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5B2408742D93EF24002D6692 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2408722D93EF24002D6692 /* Utils.swift */; }; 11 | 5B2408752D93EF24002D6692 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24086D2D93EF24002D6692 /* ContentView.swift */; }; 12 | 5B2408762D93EF24002D6692 /* ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24086E2D93EF24002D6692 /* ExampleApp.swift */; }; 13 | 5B2408772D93EF24002D6692 /* KeyframeWiggleButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2408712D93EF24002D6692 /* KeyframeWiggleButton.swift */; }; 14 | 5B2408782D93EF24002D6692 /* ExampleColorButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24086F2D93EF24002D6692 /* ExampleColorButtons.swift */; }; 15 | 5B24087A2D93EF24002D6692 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5B24086C2D93EF24002D6692 /* Assets.xcassets */; }; 16 | 5B952E2D297E5A2D003897E7 /* AnimatedTabBar in Frameworks */ = {isa = PBXBuildFile; productRef = 5B952E2C297E5A2D003897E7 /* AnimatedTabBar */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 5B24086C2D93EF24002D6692 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 21 | 5B24086D2D93EF24002D6692 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 22 | 5B24086E2D93EF24002D6692 /* ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleApp.swift; sourceTree = ""; }; 23 | 5B24086F2D93EF24002D6692 /* ExampleColorButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleColorButtons.swift; sourceTree = ""; }; 24 | 5B2408702D93EF24002D6692 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | 5B2408712D93EF24002D6692 /* KeyframeWiggleButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyframeWiggleButton.swift; sourceTree = ""; }; 26 | 5B2408722D93EF24002D6692 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 27 | 5B952DF8297E50DF003897E7 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = Example.app; path = "/Users/f3dm76/Work/!OpenSource/AnimatedTabBar/AnimatedTabBarExample/build/Debug-iphoneos/Example.app"; sourceTree = ""; }; 28 | 5B952E2A297E5953003897E7 /* AnimatedTabBar */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AnimatedTabBar; path = ..; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 5B952DF5297E50DF003897E7 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | 5B952E2D297E5A2D003897E7 /* AnimatedTabBar in Frameworks */, 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 5B2408732D93EF24002D6692 /* AnimatedTabBarExample */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 5B24086C2D93EF24002D6692 /* Assets.xcassets */, 47 | 5B24086D2D93EF24002D6692 /* ContentView.swift */, 48 | 5B24086E2D93EF24002D6692 /* ExampleApp.swift */, 49 | 5B24086F2D93EF24002D6692 /* ExampleColorButtons.swift */, 50 | 5B2408702D93EF24002D6692 /* Info.plist */, 51 | 5B2408712D93EF24002D6692 /* KeyframeWiggleButton.swift */, 52 | 5B2408722D93EF24002D6692 /* Utils.swift */, 53 | ); 54 | path = AnimatedTabBarExample; 55 | sourceTree = ""; 56 | }; 57 | 5B952DEF297E50DF003897E7 = { 58 | isa = PBXGroup; 59 | children = ( 60 | 5B952E2A297E5953003897E7 /* AnimatedTabBar */, 61 | 5B2408732D93EF24002D6692 /* AnimatedTabBarExample */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | /* End PBXGroup section */ 66 | 67 | /* Begin PBXNativeTarget section */ 68 | 5B952DF7297E50DF003897E7 /* Example */ = { 69 | isa = PBXNativeTarget; 70 | buildConfigurationList = 5B952E06297E50E0003897E7 /* Build configuration list for PBXNativeTarget "Example" */; 71 | buildPhases = ( 72 | 5B952DF4297E50DF003897E7 /* Sources */, 73 | 5B952DF5297E50DF003897E7 /* Frameworks */, 74 | 5B952DF6297E50DF003897E7 /* Resources */, 75 | ); 76 | buildRules = ( 77 | ); 78 | dependencies = ( 79 | ); 80 | name = Example; 81 | packageProductDependencies = ( 82 | 5B952E2C297E5A2D003897E7 /* AnimatedTabBar */, 83 | ); 84 | productName = Example; 85 | productReference = 5B952DF8297E50DF003897E7 /* Example.app */; 86 | productType = "com.apple.product-type.application"; 87 | }; 88 | /* End PBXNativeTarget section */ 89 | 90 | /* Begin PBXProject section */ 91 | 5B952DF0297E50DF003897E7 /* Project object */ = { 92 | isa = PBXProject; 93 | attributes = { 94 | BuildIndependentTargetsInParallel = 1; 95 | LastSwiftUpdateCheck = 1410; 96 | LastUpgradeCheck = 1540; 97 | TargetAttributes = { 98 | 5B952DF7297E50DF003897E7 = { 99 | CreatedOnToolsVersion = 14.1; 100 | }; 101 | }; 102 | }; 103 | buildConfigurationList = 5B952DF3297E50DF003897E7 /* Build configuration list for PBXProject "AnimatedTabBarExample" */; 104 | compatibilityVersion = "Xcode 14.0"; 105 | developmentRegion = en; 106 | hasScannedForEncodings = 0; 107 | knownRegions = ( 108 | en, 109 | Base, 110 | ); 111 | mainGroup = 5B952DEF297E50DF003897E7; 112 | productRefGroup = 5B952DEF297E50DF003897E7; 113 | projectDirPath = ""; 114 | projectRoot = ""; 115 | targets = ( 116 | 5B952DF7297E50DF003897E7 /* Example */, 117 | ); 118 | }; 119 | /* End PBXProject section */ 120 | 121 | /* Begin PBXResourcesBuildPhase section */ 122 | 5B952DF6297E50DF003897E7 /* Resources */ = { 123 | isa = PBXResourcesBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | 5B24087A2D93EF24002D6692 /* Assets.xcassets in Resources */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXResourcesBuildPhase section */ 131 | 132 | /* Begin PBXSourcesBuildPhase section */ 133 | 5B952DF4297E50DF003897E7 /* Sources */ = { 134 | isa = PBXSourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 5B2408742D93EF24002D6692 /* Utils.swift in Sources */, 138 | 5B2408752D93EF24002D6692 /* ContentView.swift in Sources */, 139 | 5B2408762D93EF24002D6692 /* ExampleApp.swift in Sources */, 140 | 5B2408772D93EF24002D6692 /* KeyframeWiggleButton.swift in Sources */, 141 | 5B2408782D93EF24002D6692 /* ExampleColorButtons.swift in Sources */, 142 | ); 143 | runOnlyForDeploymentPostprocessing = 0; 144 | }; 145 | /* End PBXSourcesBuildPhase section */ 146 | 147 | /* Begin XCBuildConfiguration section */ 148 | 5B952E04297E50E0003897E7 /* Debug */ = { 149 | isa = XCBuildConfiguration; 150 | buildSettings = { 151 | ALWAYS_SEARCH_USER_PATHS = NO; 152 | CLANG_ANALYZER_NONNULL = YES; 153 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 154 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 155 | CLANG_ENABLE_MODULES = YES; 156 | CLANG_ENABLE_OBJC_ARC = YES; 157 | CLANG_ENABLE_OBJC_WEAK = YES; 158 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 159 | CLANG_WARN_BOOL_CONVERSION = YES; 160 | CLANG_WARN_COMMA = YES; 161 | CLANG_WARN_CONSTANT_CONVERSION = YES; 162 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 163 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 164 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 165 | CLANG_WARN_EMPTY_BODY = YES; 166 | CLANG_WARN_ENUM_CONVERSION = YES; 167 | CLANG_WARN_INFINITE_RECURSION = YES; 168 | CLANG_WARN_INT_CONVERSION = YES; 169 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 170 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 171 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 172 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 173 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 174 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 175 | CLANG_WARN_STRICT_PROTOTYPES = YES; 176 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 177 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 178 | CLANG_WARN_UNREACHABLE_CODE = YES; 179 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 180 | COPY_PHASE_STRIP = NO; 181 | DEBUG_INFORMATION_FORMAT = dwarf; 182 | ENABLE_STRICT_OBJC_MSGSEND = YES; 183 | ENABLE_TESTABILITY = YES; 184 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 185 | GCC_C_LANGUAGE_STANDARD = gnu11; 186 | GCC_DYNAMIC_NO_PIC = NO; 187 | GCC_NO_COMMON_BLOCKS = YES; 188 | GCC_OPTIMIZATION_LEVEL = 0; 189 | GCC_PREPROCESSOR_DEFINITIONS = ( 190 | "DEBUG=1", 191 | "$(inherited)", 192 | ); 193 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 194 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 195 | GCC_WARN_UNDECLARED_SELECTOR = YES; 196 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 197 | GCC_WARN_UNUSED_FUNCTION = YES; 198 | GCC_WARN_UNUSED_VARIABLE = YES; 199 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 200 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 201 | MTL_FAST_MATH = YES; 202 | ONLY_ACTIVE_ARCH = YES; 203 | SDKROOT = iphoneos; 204 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 205 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 206 | SWIFT_VERSION = 5.0; 207 | }; 208 | name = Debug; 209 | }; 210 | 5B952E05297E50E0003897E7 /* Release */ = { 211 | isa = XCBuildConfiguration; 212 | buildSettings = { 213 | ALWAYS_SEARCH_USER_PATHS = NO; 214 | CLANG_ANALYZER_NONNULL = YES; 215 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 216 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 217 | CLANG_ENABLE_MODULES = YES; 218 | CLANG_ENABLE_OBJC_ARC = YES; 219 | CLANG_ENABLE_OBJC_WEAK = YES; 220 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 221 | CLANG_WARN_BOOL_CONVERSION = YES; 222 | CLANG_WARN_COMMA = YES; 223 | CLANG_WARN_CONSTANT_CONVERSION = YES; 224 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 225 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 226 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 227 | CLANG_WARN_EMPTY_BODY = YES; 228 | CLANG_WARN_ENUM_CONVERSION = YES; 229 | CLANG_WARN_INFINITE_RECURSION = YES; 230 | CLANG_WARN_INT_CONVERSION = YES; 231 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 232 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 233 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 234 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 235 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 236 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 237 | CLANG_WARN_STRICT_PROTOTYPES = YES; 238 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 239 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 240 | CLANG_WARN_UNREACHABLE_CODE = YES; 241 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 242 | COPY_PHASE_STRIP = NO; 243 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 244 | ENABLE_NS_ASSERTIONS = NO; 245 | ENABLE_STRICT_OBJC_MSGSEND = YES; 246 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 247 | GCC_C_LANGUAGE_STANDARD = gnu11; 248 | GCC_NO_COMMON_BLOCKS = YES; 249 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 250 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 251 | GCC_WARN_UNDECLARED_SELECTOR = YES; 252 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 253 | GCC_WARN_UNUSED_FUNCTION = YES; 254 | GCC_WARN_UNUSED_VARIABLE = YES; 255 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 256 | MTL_ENABLE_DEBUG_INFO = NO; 257 | MTL_FAST_MATH = YES; 258 | SDKROOT = iphoneos; 259 | SWIFT_COMPILATION_MODE = wholemodule; 260 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 261 | SWIFT_VERSION = 5.0; 262 | VALIDATE_PRODUCT = YES; 263 | }; 264 | name = Release; 265 | }; 266 | 5B952E07297E50E0003897E7 /* Debug */ = { 267 | isa = XCBuildConfiguration; 268 | buildSettings = { 269 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 270 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 271 | CODE_SIGN_STYLE = Automatic; 272 | CURRENT_PROJECT_VERSION = 1; 273 | DEVELOPMENT_TEAM = FZXCM5CJ7P; 274 | ENABLE_PREVIEWS = YES; 275 | GENERATE_INFOPLIST_FILE = YES; 276 | INFOPLIST_FILE = AnimatedTabBarExample/Info.plist; 277 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 278 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 279 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 280 | INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent; 281 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 282 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 283 | LD_RUNPATH_SEARCH_PATHS = ( 284 | "$(inherited)", 285 | "@executable_path/Frameworks", 286 | ); 287 | MARKETING_VERSION = 1.0; 288 | PRODUCT_BUNDLE_IDENTIFIER = com.exyte.AnimatedTabBarExample; 289 | PRODUCT_NAME = "$(TARGET_NAME)"; 290 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; 291 | SUPPORTS_MACCATALYST = NO; 292 | SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; 293 | SWIFT_EMIT_LOC_STRINGS = YES; 294 | SWIFT_VERSION = 5.0; 295 | TARGETED_DEVICE_FAMILY = "1,2"; 296 | }; 297 | name = Debug; 298 | }; 299 | 5B952E08297E50E0003897E7 /* Release */ = { 300 | isa = XCBuildConfiguration; 301 | buildSettings = { 302 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 303 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 304 | CODE_SIGN_STYLE = Automatic; 305 | CURRENT_PROJECT_VERSION = 1; 306 | DEVELOPMENT_TEAM = FZXCM5CJ7P; 307 | ENABLE_PREVIEWS = YES; 308 | GENERATE_INFOPLIST_FILE = YES; 309 | INFOPLIST_FILE = AnimatedTabBarExample/Info.plist; 310 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 311 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 312 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 313 | INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent; 314 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 315 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 316 | LD_RUNPATH_SEARCH_PATHS = ( 317 | "$(inherited)", 318 | "@executable_path/Frameworks", 319 | ); 320 | MARKETING_VERSION = 1.0; 321 | PRODUCT_BUNDLE_IDENTIFIER = com.exyte.AnimatedTabBarExample; 322 | PRODUCT_NAME = "$(TARGET_NAME)"; 323 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; 324 | SUPPORTS_MACCATALYST = NO; 325 | SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; 326 | SWIFT_EMIT_LOC_STRINGS = YES; 327 | SWIFT_VERSION = 5.0; 328 | TARGETED_DEVICE_FAMILY = "1,2"; 329 | }; 330 | name = Release; 331 | }; 332 | /* End XCBuildConfiguration section */ 333 | 334 | /* Begin XCConfigurationList section */ 335 | 5B952DF3297E50DF003897E7 /* Build configuration list for PBXProject "AnimatedTabBarExample" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | 5B952E04297E50E0003897E7 /* Debug */, 339 | 5B952E05297E50E0003897E7 /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | 5B952E06297E50E0003897E7 /* Build configuration list for PBXNativeTarget "Example" */ = { 345 | isa = XCConfigurationList; 346 | buildConfigurations = ( 347 | 5B952E07297E50E0003897E7 /* Debug */, 348 | 5B952E08297E50E0003897E7 /* Release */, 349 | ); 350 | defaultConfigurationIsVisible = 0; 351 | defaultConfigurationName = Release; 352 | }; 353 | /* End XCConfigurationList section */ 354 | 355 | /* Begin XCSwiftPackageProductDependency section */ 356 | 5B952E2C297E5A2D003897E7 /* AnimatedTabBar */ = { 357 | isa = XCSwiftPackageProductDependency; 358 | productName = AnimatedTabBar; 359 | }; 360 | /* End XCSwiftPackageProductDependency section */ 361 | }; 362 | rootObject = 5B952DF0297E50DF003897E7 /* Project object */; 363 | } 364 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 57 | 59 | 65 | 66 | 67 | 68 | 74 | 76 | 82 | 83 | 84 | 85 | 87 | 88 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab1.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab1.imageset/colorTab1.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 -0.039185 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 9.085491 16.088480 m 16 | 8.964986 16.127636 8.835176 16.127636 8.714671 16.088480 c 17 | 8.701422 16.084175 8.645322 16.064470 8.496574 15.938194 c 18 | 8.339790 15.805094 8.146935 15.613228 7.839420 15.305713 c 19 | 2.473734 9.940019 l 20 | 2.097541 9.563825 2.017257 9.475361 1.962177 9.385478 c 21 | 1.901865 9.287059 1.857421 9.179760 1.830474 9.067519 c 22 | 1.805866 8.965015 1.800081 8.845694 1.800081 8.313674 c 23 | 1.800081 3.339170 l 24 | 1.800081 2.904279 1.800781 2.632238 1.817529 2.427260 c 25 | 1.833418 2.232788 1.859153 2.179187 1.865477 2.166774 c 26 | 1.923002 2.053877 2.014791 1.962088 2.127688 1.904564 c 27 | 2.140100 1.898239 2.193701 1.872503 2.388172 1.856615 c 28 | 2.593151 1.839867 2.865191 1.839169 3.300081 1.839169 c 29 | 6.000082 1.839169 l 30 | 6.000082 5.039171 l 31 | 6.000082 6.640798 7.298457 7.939169 8.900082 7.939169 c 32 | 10.501706 7.939169 11.800081 6.640798 11.800081 5.039171 c 33 | 11.800081 1.839169 l 34 | 14.500082 1.839169 l 35 | 14.934973 1.839169 15.207012 1.839867 15.411991 1.856615 c 36 | 15.606462 1.872503 15.660064 1.898239 15.672476 1.904564 c 37 | 15.785373 1.962088 15.877161 2.053876 15.934686 2.166774 c 38 | 15.941010 2.179187 15.966745 2.232789 15.982635 2.427260 c 39 | 15.999382 2.632238 16.000082 2.904279 16.000082 3.339170 c 40 | 16.000082 8.313674 l 41 | 16.000082 8.845694 15.994298 8.965016 15.969689 9.067517 c 42 | 15.942742 9.179761 15.898297 9.287061 15.837987 9.385477 c 43 | 15.782907 9.475361 15.702621 9.563826 15.326428 9.940019 c 44 | 9.960743 15.305713 l 45 | 9.653229 15.613228 9.460372 15.805094 9.303589 15.938193 c 46 | 9.154841 16.064470 9.098741 16.084175 9.085491 16.088480 c 47 | h 48 | 8.158440 17.800383 m 49 | 8.640465 17.957001 9.159699 17.957001 9.641724 17.800383 c 50 | 9.970966 17.693405 10.234620 17.508961 10.468509 17.310404 c 51 | 10.688151 17.123941 10.933149 16.878920 11.209975 16.602066 c 52 | 16.599220 11.212810 l 53 | 16.618130 11.193901 16.636860 11.175200 16.655405 11.156684 c 54 | 16.946400 10.866146 17.191973 10.620959 17.372738 10.325975 c 55 | 17.531742 10.066504 17.648914 9.783625 17.719954 9.487724 c 56 | 17.800716 9.151325 17.800446 8.804305 17.800123 8.393111 c 57 | 17.800102 8.366898 17.800081 8.340424 17.800081 8.313674 c 58 | 17.800081 3.305832 l 59 | 17.800100 2.914328 17.800117 2.567837 17.776657 2.280683 c 60 | 17.751673 1.974897 17.695663 1.658045 17.538498 1.349590 c 61 | 17.308401 0.898003 16.941250 0.530849 16.489658 0.300753 c 62 | 16.181202 0.143587 15.864351 0.087578 15.558566 0.062593 c 63 | 15.271413 0.039133 14.924923 0.039150 14.533420 0.039169 c 64 | 11.088741 0.039169 l 65 | 10.487500 0.039169 10.000082 0.526566 10.000082 1.127827 c 66 | 10.000082 5.039171 l 67 | 10.000082 5.646684 9.507596 6.139170 8.900082 6.139170 c 68 | 8.292567 6.139170 7.800082 5.646684 7.800082 5.039171 c 69 | 7.800082 1.127827 l 70 | 7.800082 0.526566 7.312663 0.039169 6.711422 0.039169 c 71 | 3.266744 0.039169 l 72 | 2.875240 0.039150 2.528750 0.039133 2.241596 0.062593 c 73 | 1.935812 0.087578 1.618960 0.143587 1.310504 0.300753 c 74 | 0.858915 0.530849 0.491762 0.898003 0.261666 1.349590 c 75 | 0.104500 1.658045 0.048490 1.974898 0.023507 2.280683 c 76 | 0.000045 2.567838 0.000062 2.914330 0.000080 3.305837 c 77 | 0.000081 8.313674 l 78 | 0.000081 8.340419 0.000061 8.366889 0.000040 8.393099 c 79 | -0.000283 8.804298 -0.000555 9.151318 0.080209 9.487721 c 80 | 0.151249 9.783625 0.268421 10.066504 0.427424 10.325974 c 81 | 0.608189 10.620956 0.853761 10.866144 1.144751 11.156677 c 82 | 1.163298 11.175196 1.182030 11.193899 1.200941 11.212810 c 83 | 6.590200 16.602079 l 84 | 6.867023 16.878927 7.112016 17.123945 7.331655 17.310404 c 85 | 7.565544 17.508961 7.829196 17.693405 8.158440 17.800383 c 86 | h 87 | f* 88 | n 89 | Q 90 | 91 | endstream 92 | endobj 93 | 94 | 3 0 obj 95 | 3528 96 | endobj 97 | 98 | 4 0 obj 99 | << /Annots [] 100 | /Type /Page 101 | /MediaBox [ 0.000000 0.000000 17.800171 17.878662 ] 102 | /Resources 1 0 R 103 | /Contents 2 0 R 104 | /Parent 5 0 R 105 | >> 106 | endobj 107 | 108 | 5 0 obj 109 | << /Kids [ 4 0 R ] 110 | /Count 1 111 | /Type /Pages 112 | >> 113 | endobj 114 | 115 | 6 0 obj 116 | << /Pages 5 0 R 117 | /Type /Catalog 118 | >> 119 | endobj 120 | 121 | xref 122 | 0 7 123 | 0000000000 65535 f 124 | 0000000010 00000 n 125 | 0000000034 00000 n 126 | 0000003618 00000 n 127 | 0000003641 00000 n 128 | 0000003814 00000 n 129 | 0000003888 00000 n 130 | trailer 131 | << /ID [ (some) (id) ] 132 | /Root 6 0 R 133 | /Size 7 134 | >> 135 | startxref 136 | 3947 137 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab1Bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab1Bg.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab1Bg.imageset/colorTab1Bg.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 14 | 0.694118 0.490196 0.996078 scn 15 | 18.000000 9.000000 m 16 | 18.000000 4.029437 13.970563 0.000000 9.000000 0.000000 c 17 | 4.029437 0.000000 0.000000 4.029437 0.000000 9.000000 c 18 | 0.000000 13.970563 4.029437 18.000000 9.000000 18.000000 c 19 | 13.970563 18.000000 18.000000 13.970563 18.000000 9.000000 c 20 | h 21 | f 22 | n 23 | Q 24 | 25 | endstream 26 | endobj 27 | 28 | 3 0 obj 29 | 382 30 | endobj 31 | 32 | 4 0 obj 33 | << /Annots [] 34 | /Type /Page 35 | /MediaBox [ 0.000000 0.000000 18.000000 18.000000 ] 36 | /Resources 1 0 R 37 | /Contents 2 0 R 38 | /Parent 5 0 R 39 | >> 40 | endobj 41 | 42 | 5 0 obj 43 | << /Kids [ 4 0 R ] 44 | /Count 1 45 | /Type /Pages 46 | >> 47 | endobj 48 | 49 | 6 0 obj 50 | << /Pages 5 0 R 51 | /Type /Catalog 52 | >> 53 | endobj 54 | 55 | xref 56 | 0 7 57 | 0000000000 65535 f 58 | 0000000010 00000 n 59 | 0000000034 00000 n 60 | 0000000472 00000 n 61 | 0000000494 00000 n 62 | 0000000667 00000 n 63 | 0000000741 00000 n 64 | trailer 65 | << /ID [ (some) (id) ] 66 | /Root 6 0 R 67 | /Size 7 68 | >> 69 | startxref 70 | 800 71 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab2.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab2.imageset/colorTab2.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 9.404118 19.400269 m 16 | 13.419376 19.400269 16.299999 16.121956 16.299999 11.868689 c 17 | 16.299999 10.269037 l 18 | 16.299999 10.040337 16.493250 9.737230 17.020515 9.193224 c 19 | 17.088140 9.123453 17.151808 9.058767 17.290880 8.917946 c 20 | 18.372124 7.821303 18.799999 7.189513 18.799999 6.173063 c 21 | 18.799999 5.728566 18.748138 5.382032 18.532278 4.966806 c 22 | 18.076075 4.089256 17.108959 3.600269 15.663158 3.600269 c 23 | 13.751379 3.599251 l 24 | 13.122169 1.266747 11.620937 0.000050 9.400000 0.000050 c 25 | 7.155394 0.000050 5.645917 1.293888 5.028803 3.674185 c 26 | 5.048000 3.600269 l 27 | 3.136842 3.600269 l 28 | 1.648883 3.600269 0.671347 4.102564 0.234663 5.010885 c 29 | 0.043706 5.408082 0.000000 5.730491 0.000000 6.173063 c 30 | 0.000000 7.189513 0.427876 7.821303 1.509120 8.917946 c 31 | 1.648192 9.058767 1.711860 9.123453 1.779484 9.193224 c 32 | 2.306750 9.737230 2.500000 10.040337 2.500000 10.269037 c 33 | 2.500000 11.868689 l 34 | 2.500000 16.120300 5.387718 19.400269 9.404118 19.400269 c 35 | h 36 | 11.865965 3.598396 m 37 | 6.934035 3.598396 l 38 | 7.389982 2.351763 8.175776 1.800051 9.400000 1.800051 c 39 | 10.624224 1.800051 11.410018 2.351763 11.865965 3.598396 c 40 | h 41 | 9.404118 17.600269 m 42 | 6.436465 17.600269 4.300000 15.173599 4.300000 11.868689 c 43 | 4.300000 10.269037 l 44 | 4.300000 9.416475 3.910558 8.805648 3.072008 7.940474 c 45 | 2.998742 7.864882 2.929586 7.794621 2.790880 7.654184 c 46 | 2.043999 6.896667 1.800000 6.536386 1.800000 6.173063 c 47 | 1.800000 5.980961 1.813548 5.881024 1.856923 5.790802 c 48 | 1.964221 5.567617 2.289905 5.400269 3.136842 5.400269 c 49 | 15.663158 5.400269 l 50 | 16.483238 5.400269 16.816523 5.568780 16.935198 5.797064 c 51 | 16.984650 5.892188 17.000000 5.994765 17.000000 6.173063 c 52 | 17.000000 6.536386 16.756001 6.896667 16.009119 7.654184 c 53 | 15.870413 7.794621 15.801259 7.864882 15.727993 7.940474 c 54 | 14.889442 8.805648 14.500000 9.416475 14.500000 10.269037 c 55 | 14.500000 11.868689 l 56 | 14.500000 15.175917 12.369743 17.600269 9.404118 17.600269 c 57 | h 58 | f 59 | n 60 | Q 61 | 62 | endstream 63 | endobj 64 | 65 | 3 0 obj 66 | 2006 67 | endobj 68 | 69 | 4 0 obj 70 | << /Annots [] 71 | /Type /Page 72 | /MediaBox [ 0.000000 0.000000 18.799988 19.400269 ] 73 | /Resources 1 0 R 74 | /Contents 2 0 R 75 | /Parent 5 0 R 76 | >> 77 | endobj 78 | 79 | 5 0 obj 80 | << /Kids [ 4 0 R ] 81 | /Count 1 82 | /Type /Pages 83 | >> 84 | endobj 85 | 86 | 6 0 obj 87 | << /Pages 5 0 R 88 | /Type /Catalog 89 | >> 90 | endobj 91 | 92 | xref 93 | 0 7 94 | 0000000000 65535 f 95 | 0000000010 00000 n 96 | 0000000034 00000 n 97 | 0000002096 00000 n 98 | 0000002119 00000 n 99 | 0000002292 00000 n 100 | 0000002366 00000 n 101 | trailer 102 | << /ID [ (some) (id) ] 103 | /Root 6 0 R 104 | /Size 7 105 | >> 106 | startxref 107 | 2425 108 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab2Bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab2Bg.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab2Bg.imageset/colorTab2Bg.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 0.965926 0.258819 -0.258819 0.965926 4.622830 -3.922373 cm 14 | 0.996078 0.490196 0.490196 scn 15 | 0.000000 17.595947 m 16 | 0.000000 18.700518 0.895431 19.595947 2.000000 19.595947 c 17 | 14.000000 19.595947 l 18 | 15.104569 19.595947 16.000000 18.700518 16.000000 17.595947 c 19 | 16.000000 5.595947 l 20 | 16.000000 4.491378 15.104569 3.595947 14.000000 3.595947 c 21 | 2.000000 3.595947 l 22 | 0.895431 3.595947 0.000000 4.491378 0.000000 5.595947 c 23 | 0.000000 17.595947 l 24 | h 25 | f 26 | n 27 | Q 28 | 29 | endstream 30 | endobj 31 | 32 | 3 0 obj 33 | 469 34 | endobj 35 | 36 | 4 0 obj 37 | << /Annots [] 38 | /Type /Page 39 | /MediaBox [ 0.000000 0.000000 18.697937 18.697998 ] 40 | /Resources 1 0 R 41 | /Contents 2 0 R 42 | /Parent 5 0 R 43 | >> 44 | endobj 45 | 46 | 5 0 obj 47 | << /Kids [ 4 0 R ] 48 | /Count 1 49 | /Type /Pages 50 | >> 51 | endobj 52 | 53 | 6 0 obj 54 | << /Pages 5 0 R 55 | /Type /Catalog 56 | >> 57 | endobj 58 | 59 | xref 60 | 0 7 61 | 0000000000 65535 f 62 | 0000000010 00000 n 63 | 0000000034 00000 n 64 | 0000000559 00000 n 65 | 0000000581 00000 n 66 | 0000000754 00000 n 67 | 0000000828 00000 n 68 | trailer 69 | << /ID [ (some) (id) ] 70 | /Root 6 0 R 71 | /Size 7 72 | >> 73 | startxref 74 | 887 75 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab3.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab3.imageset/colorTab3.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 12.490288 19.800049 m 16 | 14.658197 19.800049 15.692332 19.600348 16.766552 19.025848 c 17 | 17.738209 18.506201 18.506151 17.738258 19.025799 16.766602 c 18 | 19.600298 15.692383 19.799999 14.658246 19.799999 12.490335 c 19 | 19.799999 7.309761 l 20 | 19.799999 5.141851 19.600298 4.107717 19.025799 3.033497 c 21 | 18.506151 2.061840 17.738209 1.293898 16.766552 0.774250 c 22 | 15.692332 0.199751 14.658197 0.000050 12.490288 0.000050 c 23 | 7.309713 0.000050 l 24 | 5.141803 0.000050 4.107666 0.199751 3.033447 0.774250 c 25 | 2.061790 1.293898 1.293848 2.061840 0.774200 3.033497 c 26 | 0.199701 4.107717 0.000000 5.141851 0.000000 7.309761 c 27 | 0.000000 12.490335 l 28 | 0.000000 14.658246 0.199701 15.692383 0.774200 16.766602 c 29 | 1.293848 17.738258 2.061790 18.506201 3.033447 19.025848 c 30 | 4.107666 19.600348 5.141803 19.800049 7.309713 19.800049 c 31 | 12.490288 19.800049 l 32 | h 33 | 12.490288 18.000050 m 34 | 7.309713 18.000050 l 35 | 5.413539 18.000050 4.660126 17.854559 3.882325 17.438585 c 36 | 3.224351 17.086697 2.713351 16.575697 2.361464 15.917725 c 37 | 1.945491 15.139923 1.800000 14.386509 1.800000 12.490335 c 38 | 1.800000 7.309761 l 39 | 1.800000 5.413588 1.945491 4.660175 2.361464 3.882374 c 40 | 2.713351 3.224401 3.224351 2.713402 3.882325 2.361513 c 41 | 4.660126 1.945541 5.413539 1.800049 7.309713 1.800049 c 42 | 12.490288 1.800049 l 43 | 14.386461 1.800049 15.139874 1.945541 15.917675 2.361513 c 44 | 16.575647 2.713402 17.086647 3.224401 17.438536 3.882374 c 45 | 17.854507 4.660175 18.000000 5.413588 18.000000 7.309761 c 46 | 18.000000 12.490335 l 47 | 18.000000 14.386509 17.854507 15.139923 17.438536 15.917725 c 48 | 17.086647 16.575697 16.575647 17.086697 15.917675 17.438585 c 49 | 15.139874 17.854559 14.386461 18.000050 12.490288 18.000050 c 50 | h 51 | f 52 | n 53 | Q 54 | 55 | endstream 56 | endobj 57 | 58 | 3 0 obj 59 | 1757 60 | endobj 61 | 62 | 4 0 obj 63 | << /Annots [] 64 | /Type /Page 65 | /MediaBox [ 0.000000 0.000000 19.799999 19.800049 ] 66 | /Resources 1 0 R 67 | /Contents 2 0 R 68 | /Parent 5 0 R 69 | >> 70 | endobj 71 | 72 | 5 0 obj 73 | << /Kids [ 4 0 R ] 74 | /Count 1 75 | /Type /Pages 76 | >> 77 | endobj 78 | 79 | 6 0 obj 80 | << /Pages 5 0 R 81 | /Type /Catalog 82 | >> 83 | endobj 84 | 85 | xref 86 | 0 7 87 | 0000000000 65535 f 88 | 0000000010 00000 n 89 | 0000000034 00000 n 90 | 0000001847 00000 n 91 | 0000001870 00000 n 92 | 0000002043 00000 n 93 | 0000002117 00000 n 94 | trailer 95 | << /ID [ (some) (id) ] 96 | /Root 6 0 R 97 | /Size 7 98 | >> 99 | startxref 100 | 2176 101 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab3Bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab3Bg.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab3Bg.imageset/colorTab3Bg.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 0.866025 0.500000 -0.500000 0.866025 8.830150 -9.849356 cm 14 | 0.682431 0.996078 0.490196 scn 15 | 9.000000 25.022259 m 16 | 9.618802 25.379524 10.381198 25.379524 11.000000 25.022259 c 17 | 17.660255 21.176960 l 18 | 18.279058 20.819695 18.660255 20.159439 18.660255 19.444908 c 19 | 18.660255 11.754310 l 20 | 18.660255 11.039779 18.279058 10.379525 17.660255 10.022259 c 21 | 11.000000 6.176960 l 22 | 10.381198 5.819695 9.618802 5.819695 9.000000 6.176960 c 23 | 2.339746 10.022259 l 24 | 1.720943 10.379524 1.339746 11.039779 1.339746 11.754310 c 25 | 1.339746 19.444908 l 26 | 1.339746 20.159439 1.720943 20.819695 2.339746 21.176960 c 27 | 9.000000 25.022259 l 28 | h 29 | f 30 | n 31 | Q 32 | 33 | endstream 34 | endobj 35 | 36 | 3 0 obj 37 | 637 38 | endobj 39 | 40 | 4 0 obj 41 | << /Annots [] 42 | /Type /Page 43 | /MediaBox [ 0.000000 0.000000 19.381199 17.320557 ] 44 | /Resources 1 0 R 45 | /Contents 2 0 R 46 | /Parent 5 0 R 47 | >> 48 | endobj 49 | 50 | 5 0 obj 51 | << /Kids [ 4 0 R ] 52 | /Count 1 53 | /Type /Pages 54 | >> 55 | endobj 56 | 57 | 6 0 obj 58 | << /Pages 5 0 R 59 | /Type /Catalog 60 | >> 61 | endobj 62 | 63 | xref 64 | 0 7 65 | 0000000000 65535 f 66 | 0000000010 00000 n 67 | 0000000034 00000 n 68 | 0000000727 00000 n 69 | 0000000749 00000 n 70 | 0000000922 00000 n 71 | 0000000996 00000 n 72 | trailer 73 | << /ID [ (some) (id) ] 74 | /Root 6 0 R 75 | /Size 7 76 | >> 77 | startxref 78 | 1055 79 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab3Plus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab3Plus.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab3Plus.imageset/colorTab3Plus.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 5.000000 10.000000 m 16 | 5.497056 10.000000 5.900000 9.597056 5.900000 9.100000 c 17 | 5.900000 5.900000 l 18 | 9.099998 5.900000 l 19 | 9.597054 5.900000 9.999998 5.497057 9.999998 5.000000 c 20 | 9.999998 4.502944 9.597054 4.100000 9.099998 4.100000 c 21 | 5.900000 4.100000 l 22 | 5.900000 0.900000 l 23 | 5.900000 0.402944 5.497056 0.000000 5.000000 0.000000 c 24 | 4.502944 0.000000 4.100000 0.402944 4.100000 0.900000 c 25 | 4.100000 4.100000 l 26 | 0.900000 4.100000 l 27 | 0.402944 4.100000 0.000000 4.502944 0.000000 5.000000 c 28 | 0.000000 5.497057 0.402944 5.900000 0.900000 5.900000 c 29 | 4.100000 5.900000 l 30 | 4.100000 9.100000 l 31 | 4.100000 9.597056 4.502944 10.000000 5.000000 10.000000 c 32 | h 33 | f* 34 | n 35 | Q 36 | 37 | endstream 38 | endobj 39 | 40 | 3 0 obj 41 | 760 42 | endobj 43 | 44 | 4 0 obj 45 | << /Annots [] 46 | /Type /Page 47 | /MediaBox [ 0.000000 0.000000 9.999998 10.000000 ] 48 | /Resources 1 0 R 49 | /Contents 2 0 R 50 | /Parent 5 0 R 51 | >> 52 | endobj 53 | 54 | 5 0 obj 55 | << /Kids [ 4 0 R ] 56 | /Count 1 57 | /Type /Pages 58 | >> 59 | endobj 60 | 61 | 6 0 obj 62 | << /Pages 5 0 R 63 | /Type /Catalog 64 | >> 65 | endobj 66 | 67 | xref 68 | 0 7 69 | 0000000000 65535 f 70 | 0000000010 00000 n 71 | 0000000034 00000 n 72 | 0000000850 00000 n 73 | 0000000872 00000 n 74 | 0000001044 00000 n 75 | 0000001118 00000 n 76 | trailer 77 | << /ID [ (some) (id) ] 78 | /Root 6 0 R 79 | /Size 7 80 | >> 81 | startxref 82 | 1177 83 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab4.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab4.imageset/colorTab4.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 12.900000 19.400024 m 16 | 13.397057 19.400024 13.799999 18.997080 13.799999 18.500025 c 17 | 13.799999 17.708763 l 18 | 14.332357 17.642149 14.811954 17.521997 15.261057 17.293167 c 19 | 16.136009 16.847357 16.847370 16.135998 17.293180 15.261044 c 20 | 17.572964 14.711938 17.690283 14.117247 17.745920 13.436269 c 21 | 17.800014 12.774173 17.800009 11.955959 17.799999 10.938685 c 22 | 17.799999 6.861290 l 23 | 17.800009 5.844016 17.800014 5.025802 17.745920 4.363705 c 24 | 17.690283 3.682728 17.572964 3.088036 17.293180 2.538931 c 25 | 16.847370 1.663979 16.136009 0.952618 15.261057 0.506807 c 26 | 14.711952 0.227024 14.117260 0.109705 13.436283 0.054068 c 27 | 12.774186 -0.000027 11.955972 -0.000021 10.938698 -0.000011 c 28 | 6.861303 -0.000011 l 29 | 5.844028 -0.000021 5.025815 -0.000027 4.363719 0.054068 c 30 | 3.682742 0.109705 3.088050 0.227024 2.538944 0.506807 c 31 | 1.663991 0.952618 0.952631 1.663979 0.506820 2.538931 c 32 | 0.227037 3.088036 0.109718 3.682728 0.054080 4.363705 c 33 | -0.000015 5.025803 -0.000008 5.844018 0.000000 6.861293 c 34 | 0.000000 10.938682 l 35 | -0.000008 11.955957 -0.000015 12.774172 0.054080 13.436269 c 36 | 0.109718 14.117247 0.227037 14.711938 0.506820 15.261044 c 37 | 0.952631 16.135998 1.663991 16.847357 2.538944 17.293167 c 38 | 2.988047 17.521997 3.467643 17.642149 4.000000 17.708763 c 39 | 4.000000 18.500025 l 40 | 4.000000 18.997080 4.402944 19.400024 4.900000 19.400024 c 41 | 5.397057 19.400024 5.800000 18.997080 5.800000 18.500025 c 42 | 5.800000 17.797155 l 43 | 6.127334 17.799994 6.480320 17.799992 6.861216 17.799988 c 44 | 10.938695 17.799988 l 45 | 11.319590 17.799992 11.672667 17.799994 12.000000 17.797155 c 46 | 12.000000 18.500025 l 47 | 12.000000 18.997080 12.402944 19.400024 12.900000 19.400024 c 48 | h 49 | 4.000000 15.889336 m 50 | 4.000000 15.300024 l 51 | 4.000000 14.802968 4.402944 14.400024 4.900000 14.400024 c 52 | 5.397057 14.400024 5.800000 14.802968 5.800000 15.300024 c 53 | 5.800000 15.997021 l 54 | 6.124832 15.999884 6.488500 15.999988 6.900001 15.999988 c 55 | 10.900001 15.999988 l 56 | 11.311501 15.999988 11.675168 15.999884 12.000000 15.997021 c 57 | 12.000000 15.300024 l 58 | 12.000000 14.802968 12.402944 14.400024 12.900000 14.400024 c 59 | 13.397057 14.400024 13.799999 14.802968 13.799999 15.300024 c 60 | 13.799999 15.889336 l 61 | 14.078348 15.840424 14.277958 15.773895 14.443874 15.689356 c 62 | 14.980137 15.416117 15.416130 14.980123 15.689369 14.443861 c 63 | 15.818312 14.190797 15.905355 13.859355 15.951899 13.289692 c 64 | 15.984655 12.888784 15.995110 12.409369 15.998444 11.799988 c 65 | 1.801558 11.799988 l 66 | 1.804891 12.409369 1.815347 12.888784 1.848102 13.289692 c 67 | 1.894646 13.859355 1.981689 14.190797 2.110632 14.443861 c 68 | 2.383871 14.980123 2.819865 15.416117 3.356127 15.689356 c 69 | 3.522044 15.773895 3.721653 15.840424 4.000000 15.889336 c 70 | h 71 | 1.800000 9.999988 m 72 | 16.000000 9.999988 l 73 | 16.000000 6.899987 l 74 | 16.000000 5.835038 15.999302 5.090453 15.951899 4.510284 c 75 | 15.905355 3.940620 15.818312 3.609177 15.689369 3.356113 c 76 | 15.416130 2.819851 14.980137 2.383858 14.443874 2.110619 c 77 | 14.190811 1.981676 13.859367 1.894632 13.289703 1.848089 c 78 | 12.709535 1.800686 11.964950 1.799988 10.900001 1.799988 c 79 | 6.900001 1.799988 l 80 | 5.835052 1.799988 5.090466 1.800686 4.510296 1.848089 c 81 | 3.940633 1.894632 3.609191 1.981676 3.356127 2.110619 c 82 | 2.819865 2.383858 2.383871 2.819851 2.110632 3.356113 c 83 | 1.981689 3.609177 1.894646 3.940620 1.848102 4.510284 c 84 | 1.800700 5.090453 1.800000 5.835038 1.800000 6.899987 c 85 | 1.800000 9.999988 l 86 | h 87 | f* 88 | n 89 | Q 90 | 91 | endstream 92 | endobj 93 | 94 | 3 0 obj 95 | 3430 96 | endobj 97 | 98 | 4 0 obj 99 | << /Annots [] 100 | /Type /Page 101 | /MediaBox [ 0.000000 0.000000 17.799988 19.400024 ] 102 | /Resources 1 0 R 103 | /Contents 2 0 R 104 | /Parent 5 0 R 105 | >> 106 | endobj 107 | 108 | 5 0 obj 109 | << /Kids [ 4 0 R ] 110 | /Count 1 111 | /Type /Pages 112 | >> 113 | endobj 114 | 115 | 6 0 obj 116 | << /Pages 5 0 R 117 | /Type /Catalog 118 | >> 119 | endobj 120 | 121 | xref 122 | 0 7 123 | 0000000000 65535 f 124 | 0000000010 00000 n 125 | 0000000034 00000 n 126 | 0000003520 00000 n 127 | 0000003543 00000 n 128 | 0000003716 00000 n 129 | 0000003790 00000 n 130 | trailer 131 | << /ID [ (some) (id) ] 132 | /Root 6 0 R 133 | /Size 7 134 | >> 135 | startxref 136 | 3849 137 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab4Bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab4Bg.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab4Bg.imageset/colorTab4Bg.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 -1.000000 -1.258942 19.892090 cm 14 | 0.996078 0.793725 0.490196 scn 15 | 20.930082 6.474808 m 16 | 12.708102 0.495186 l 17 | 11.780179 -0.179667 10.475931 0.062853 9.852619 1.026155 c 18 | 1.581361 13.809008 l 19 | 0.819045 14.987133 1.475331 16.563526 2.848479 16.852610 c 20 | 17.080318 19.848785 l 21 | 18.146471 20.073238 19.196131 19.403028 19.441120 18.341408 c 22 | 21.702522 8.542000 l 23 | 21.882896 7.760382 21.578819 6.946616 20.930082 6.474808 c 24 | h 25 | f 26 | n 27 | Q 28 | 29 | endstream 30 | endobj 31 | 32 | 3 0 obj 33 | 475 34 | endobj 35 | 36 | 4 0 obj 37 | << /Annots [] 38 | /Type /Page 39 | /MediaBox [ 0.000000 0.000000 20.494904 19.779663 ] 40 | /Resources 1 0 R 41 | /Contents 2 0 R 42 | /Parent 5 0 R 43 | >> 44 | endobj 45 | 46 | 5 0 obj 47 | << /Kids [ 4 0 R ] 48 | /Count 1 49 | /Type /Pages 50 | >> 51 | endobj 52 | 53 | 6 0 obj 54 | << /Pages 5 0 R 55 | /Type /Catalog 56 | >> 57 | endobj 58 | 59 | xref 60 | 0 7 61 | 0000000000 65535 f 62 | 0000000010 00000 n 63 | 0000000034 00000 n 64 | 0000000565 00000 n 65 | 0000000587 00000 n 66 | 0000000760 00000 n 67 | 0000000834 00000 n 68 | trailer 69 | << /ID [ (some) (id) ] 70 | /Root 6 0 R 71 | /Size 7 72 | >> 73 | startxref 74 | 893 75 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab5.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab5.imageset/colorTab5.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 -0.276611 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 10.493708 19.458113 m 16 | 11.701565 19.420515 12.487005 18.755970 12.901129 17.503208 c 17 | 12.966720 17.288975 l 18 | 13.017464 17.097178 l 19 | 13.035932 17.023306 13.058914 16.944658 13.085872 16.862976 c 20 | 13.143207 16.703613 l 21 | 13.177207 16.686613 l 22 | 13.246193 16.709414 l 23 | 13.379820 16.760599 l 24 | 13.535681 16.828426 l 25 | 14.949525 17.486624 16.037106 17.364468 16.922733 16.391245 c 26 | 17.047892 16.246416 l 27 | 17.868092 15.229907 l 28 | 18.599001 14.267565 18.576845 13.238953 17.863884 12.128729 c 29 | 17.738672 11.942934 l 30 | 17.621550 11.782795 l 31 | 17.574776 11.720644 17.527132 11.651752 17.479681 11.577721 c 32 | 17.408785 11.463018 l 33 | 17.375206 11.405613 l 34 | 17.379206 11.385612 l 35 | 17.470865 11.325136 l 36 | 17.597393 11.248722 l 37 | 17.750767 11.165386 l 38 | 19.139883 10.456489 19.713205 9.524255 19.492010 8.229216 c 39 | 19.455009 8.041727 l 40 | 19.210903 6.983488 l 41 | 19.052801 6.298673 18.928638 5.974453 18.440117 5.529606 c 42 | 17.965546 5.097463 17.424076 4.919075 16.708553 4.859888 c 43 | 16.488567 4.845573 l 44 | 16.290270 4.839275 l 45 | 16.213341 4.837884 16.130657 4.833100 16.044083 4.825066 c 46 | 15.863206 4.803612 l 47 | 15.876353 4.661219 l 48 | 15.889703 4.565422 l 49 | 15.921973 4.386688 l 50 | 16.245256 2.861019 15.881578 1.828791 14.734076 1.184788 c 51 | 14.564805 1.095417 l 52 | 13.389844 0.524904 l 53 | 12.287747 0.029207 11.290483 0.282183 10.369096 1.226618 c 54 | 10.216228 1.390415 l 55 | 10.086541 1.540558 l 56 | 10.035982 1.600735 9.978943 1.663300 9.916780 1.726824 c 57 | 9.819861 1.822649 l 58 | 9.770206 1.868612 l 59 | 9.678546 1.781399 l 60 | 9.573542 1.673374 l 61 | 9.455873 1.540558 l 62 | 8.503391 0.406891 7.498107 -0.000061 6.279644 0.473860 c 63 | 6.104111 0.547573 l 64 | 5.052697 1.058567 l 65 | 4.740369 1.218380 l 66 | 4.264308 1.478361 3.997156 1.727362 3.736094 2.278643 c 67 | 3.461255 2.859015 3.442791 3.429075 3.576024 4.161814 c 68 | 3.620440 4.386688 l 69 | 3.636349 4.461767 3.650259 4.543195 3.661888 4.629129 c 70 | 3.680207 4.800611 l 71 | 3.676207 4.804613 l 72 | 3.572529 4.818495 l 73 | 3.426035 4.831638 l 74 | 3.252143 4.839275 l 75 | 1.692853 4.867479 0.768891 5.454037 0.399526 6.716997 c 76 | 0.350524 6.902035 l 77 | 0.058941 8.175219 l 78 | -0.176133 9.360576 0.294693 10.275375 1.422189 10.960695 c 79 | 1.616177 11.072798 l 80 | 1.791645 11.165386 l 81 | 1.860417 11.200482 1.932892 11.241183 2.007439 11.286535 c 82 | 2.162206 11.387613 l 83 | 2.166207 11.406612 l 84 | 2.103657 11.514500 l 85 | 2.022847 11.639675 l 86 | 1.920862 11.782795 l 87 | 0.983093 13.028896 0.876459 14.118111 1.644281 15.186729 c 88 | 1.759924 15.339264 l 89 | 2.583690 16.352884 l 90 | 3.373039 17.267904 4.383780 17.460094 5.617975 16.993542 c 91 | 5.825744 16.909695 l 92 | 6.006733 16.828426 l 93 | 6.074826 16.796726 6.149334 16.765501 6.228620 16.735409 c 94 | 6.364207 16.687613 l 95 | 6.400207 16.704613 l 96 | 6.433833 16.793257 l 97 | 6.478916 16.931204 l 98 | 6.524950 17.097178 l 99 | 6.884068 18.533649 7.609215 19.340103 8.914301 19.448288 c 100 | 9.104710 19.458984 l 101 | 10.493708 19.458113 l 102 | h 103 | 10.437704 17.658985 m 104 | 9.104710 17.658985 l 105 | 8.965302 17.648769 l 106 | 8.679241 17.611521 8.492382 17.457119 8.312609 16.817099 c 107 | 8.271207 16.660612 l 108 | 8.214741 16.454851 l 109 | 8.109782 16.102337 7.951117 15.705651 7.746797 15.320514 c 110 | 7.342271 15.175551 6.957843 14.988379 6.599438 14.762402 c 111 | 6.177720 14.847895 5.775603 14.973291 5.440033 15.111989 c 112 | 5.090022 15.266917 l 113 | 4.841116 15.373535 4.654682 15.427927 4.506945 15.441162 c 114 | 4.422755 15.444254 l 115 | 4.245142 15.440540 4.127869 15.367594 4.014579 15.251650 c 116 | 3.946632 15.177134 l 117 | 3.157497 14.204897 l 118 | 3.062786 14.079529 l 119 | 2.879387 13.815208 2.851952 13.579510 3.257653 13.004129 c 120 | 3.485848 12.688309 l 121 | 3.697752 12.378579 3.910234 11.996822 4.083724 11.586887 c 122 | 3.954299 11.202609 3.862728 10.800927 3.813659 10.385477 c 123 | 3.479791 10.096462 3.124022 9.848822 2.800010 9.664738 c 124 | 2.457747 9.481647 l 125 | 1.840876 9.142347 1.762210 8.918476 1.811177 8.600510 c 126 | 1.824557 8.525366 l 127 | 2.104849 7.304951 l 128 | 2.145330 7.153133 l 129 | 2.240706 6.845881 2.409549 6.679152 3.112728 6.644609 c 130 | 3.500070 6.630116 l 131 | 3.871015 6.606766 4.298033 6.540261 4.723163 6.426233 c 132 | 4.947935 6.077226 5.207912 5.753036 5.499310 5.458838 c 133 | 5.515915 4.932175 5.467224 4.418863 5.381342 4.013561 c 134 | 5.180239 3.064491 5.367450 2.911585 5.764836 2.714144 c 135 | 6.890920 2.166502 l 136 | 7.010244 2.112833 7.116879 2.076675 7.227695 2.078030 c 137 | 7.294822 2.083641 l 138 | 7.475883 2.111280 7.676285 2.245432 7.965128 2.568346 c 139 | 8.222923 2.863262 l 140 | 8.479630 3.142004 8.807534 3.437672 9.171436 3.700214 c 141 | 9.469390 3.678072 l 142 | 9.771207 3.670612 l 143 | 10.073050 3.678175 l 144 | 10.371181 3.701035 l 145 | 10.734913 3.437809 11.062789 3.142027 11.319491 2.863266 c 146 | 11.577286 2.568346 l 147 | 11.902234 2.205069 12.115250 2.080692 12.314718 2.078030 c 148 | 12.380841 2.081598 l 149 | 12.439411 2.088425 12.497751 2.104803 12.558421 2.127684 c 150 | 12.651494 2.166502 l 151 | 13.777577 2.714144 l 152 | 13.916398 2.787739 l 153 | 14.215699 2.962252 14.337036 3.183125 14.161071 4.013561 c 154 | 14.075190 4.418863 14.026499 4.932175 14.044337 5.458681 c 155 | 14.334501 5.753036 14.594480 6.077226 14.819507 6.427898 c 156 | 15.244981 6.540612 15.671779 6.606840 16.042484 6.630131 c 157 | 16.429684 6.644609 l 158 | 17.241045 6.684466 17.341011 6.900311 17.437563 7.304951 c 159 | 17.701067 8.446310 l 160 | 17.791670 8.852324 17.796440 9.090147 17.084665 9.481647 c 161 | 16.742384 9.664753 l 162 | 16.418343 9.848875 16.062580 10.096645 15.728969 10.386271 c 163 | 15.679686 10.800925 15.588114 11.202609 15.458171 11.587719 c 164 | 15.632093 11.996962 15.844646 12.378602 16.056562 12.688313 c 165 | 16.284760 13.004129 l 166 | 16.690460 13.579510 16.663027 13.815208 16.479628 14.079529 c 167 | 16.434662 14.141202 l 168 | 15.647742 15.115232 l 169 | 15.506856 15.286625 15.388638 15.409326 15.195703 15.437998 c 170 | 15.119658 15.444254 l 171 | 14.959806 15.447596 14.751079 15.394859 14.452392 15.266917 c 172 | 14.102513 15.112050 l 173 | 13.767186 14.973473 13.365411 14.848332 12.944126 14.763969 c 174 | 12.584358 14.988563 12.199075 15.176097 11.793633 15.319609 c 175 | 11.599072 15.690064 11.445318 16.070583 11.340509 16.412334 c 176 | 11.227038 16.826906 l 177 | 11.035200 17.504293 10.834763 17.631302 10.513930 17.655117 c 178 | 10.437704 17.658985 l 179 | h 180 | 9.771207 13.470613 m 181 | 11.869888 13.470613 13.571207 11.769295 13.571207 9.670612 c 182 | 13.571207 7.571930 11.869888 5.870613 9.771207 5.870613 c 183 | 7.672524 5.870613 5.971207 7.571930 5.971207 9.670612 c 184 | 5.971207 11.769295 7.672524 13.470613 9.771207 13.470613 c 185 | h 186 | 9.771207 11.670612 m 187 | 8.666637 11.670612 7.771207 10.775182 7.771207 9.670612 c 188 | 7.771207 8.566043 8.666637 7.670612 9.771207 7.670612 c 189 | 10.875776 7.670612 11.771207 8.566043 11.771207 9.670612 c 190 | 11.771207 10.775182 10.875776 11.670612 9.771207 11.670612 c 191 | h 192 | f 193 | n 194 | Q 195 | 196 | endstream 197 | endobj 198 | 199 | 3 0 obj 200 | 6386 201 | endobj 202 | 203 | 4 0 obj 204 | << /Annots [] 205 | /Type /Page 206 | /MediaBox [ 0.000000 0.000000 19.538147 19.182373 ] 207 | /Resources 1 0 R 208 | /Contents 2 0 R 209 | /Parent 5 0 R 210 | >> 211 | endobj 212 | 213 | 5 0 obj 214 | << /Kids [ 4 0 R ] 215 | /Count 1 216 | /Type /Pages 217 | >> 218 | endobj 219 | 220 | 6 0 obj 221 | << /Pages 5 0 R 222 | /Type /Catalog 223 | >> 224 | endobj 225 | 226 | xref 227 | 0 7 228 | 0000000000 65535 f 229 | 0000000010 00000 n 230 | 0000000034 00000 n 231 | 0000006476 00000 n 232 | 0000006499 00000 n 233 | 0000006672 00000 n 234 | 0000006746 00000 n 235 | trailer 236 | << /ID [ (some) (id) ] 237 | /Root 6 0 R 238 | /Size 7 239 | >> 240 | startxref 241 | 6805 242 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab5Bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "colorTab5Bg.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/colorTab5Bg.imageset/colorTab5Bg.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 -1.065308 0.721558 cm 14 | 0.490196 0.753255 0.996078 scn 15 | 9.125033 16.631981 m 16 | 9.505619 17.319738 10.494382 17.319736 10.874968 16.631981 c 17 | 10.890407 16.604080 l 18 | 11.190012 16.062662 11.904458 15.920551 12.388449 16.306103 c 19 | 12.413389 16.325970 l 20 | 13.028197 16.815731 13.941695 16.437346 14.030117 15.656298 c 21 | 14.033704 15.624614 l 22 | 14.103312 15.009754 14.708990 14.605055 15.303683 14.776042 c 23 | 15.334329 14.784853 l 24 | 16.089760 15.002056 16.788921 14.302895 16.571718 13.547462 c 25 | 16.562906 13.516817 l 26 | 16.391920 12.922123 16.796621 12.316446 17.411480 12.246839 c 27 | 17.443165 12.243252 l 28 | 18.224213 12.154829 18.602596 11.241331 18.112835 10.626524 c 29 | 18.092966 10.601583 l 30 | 17.707417 10.117592 17.849529 9.403147 18.390947 9.103540 c 31 | 18.418848 9.088101 l 32 | 19.106604 8.707516 19.106604 7.718753 18.418846 7.338168 c 33 | 18.390945 7.322728 l 34 | 17.849527 7.023123 17.707417 6.308678 18.092968 5.824686 c 35 | 18.112835 5.799746 l 36 | 18.602596 5.184937 18.224213 4.271440 17.443165 4.183018 c 37 | 17.411480 4.179431 l 38 | 16.796621 4.109823 16.391920 3.504146 16.562908 2.909451 c 39 | 16.571718 2.878805 l 40 | 16.788921 2.123373 16.089760 1.424213 15.334329 1.641417 c 41 | 15.303681 1.650229 l 42 | 14.708988 1.821215 14.103312 1.416513 14.033704 0.801655 c 43 | 14.030117 0.769970 l 44 | 13.941695 -0.011078 13.028197 -0.389462 12.413388 0.100300 c 45 | 12.388448 0.120169 l 46 | 11.904457 0.505718 11.190012 0.363605 10.890406 -0.177813 c 47 | 10.874967 -0.205713 l 48 | 10.494381 -0.893469 9.505618 -0.893469 9.125033 -0.205711 c 49 | 9.109593 -0.177811 l 50 | 8.809988 0.363607 8.095543 0.505718 7.611552 0.120167 c 51 | 7.586611 0.100300 l 52 | 6.971803 -0.389462 6.058305 -0.011078 5.969883 0.769970 c 53 | 5.966296 0.801655 l 54 | 5.896688 1.416513 5.291010 1.821215 4.696317 1.650227 c 55 | 4.665671 1.641417 l 56 | 3.910239 1.424213 3.211079 2.123375 3.428282 2.878807 c 57 | 3.437093 2.909452 l 58 | 3.608080 3.504146 3.203379 4.109823 2.588520 4.179431 c 59 | 2.556836 4.183018 l 60 | 1.775787 4.271440 1.397405 5.184937 1.887166 5.799747 c 61 | 1.907034 5.824687 l 62 | 2.292584 6.308679 2.150471 7.023123 1.609054 7.322729 c 63 | 1.581153 7.338168 l 64 | 0.893397 7.718754 0.893398 8.707517 1.581154 9.088102 c 65 | 1.609055 9.103541 l 66 | 2.150473 9.403147 2.292583 10.117593 1.907033 10.601583 c 67 | 1.887165 10.626524 l 68 | 1.397404 11.241333 1.775789 12.154830 2.556837 12.243252 c 69 | 2.588521 12.246839 l 70 | 3.203380 12.316446 3.608080 12.922125 3.437093 13.516817 c 71 | 3.428282 13.547462 l 72 | 3.211079 14.302895 3.910241 15.002055 4.665673 14.784853 c 73 | 4.696318 14.776041 l 74 | 5.291011 14.605055 5.896688 15.009756 5.966296 15.624615 c 75 | 5.969883 15.656300 l 76 | 6.058305 16.437347 6.971803 16.815729 7.586611 16.325970 c 77 | 7.611552 16.306101 l 78 | 8.095544 15.920550 8.809988 16.062664 9.109594 16.604080 c 79 | 9.125033 16.631981 l 80 | h 81 | f 82 | n 83 | Q 84 | 85 | endstream 86 | endobj 87 | 88 | 3 0 obj 89 | 2711 90 | endobj 91 | 92 | 4 0 obj 93 | << /Annots [] 94 | /Type /Page 95 | /MediaBox [ 0.000000 0.000000 17.869385 17.869385 ] 96 | /Resources 1 0 R 97 | /Contents 2 0 R 98 | /Parent 5 0 R 99 | >> 100 | endobj 101 | 102 | 5 0 obj 103 | << /Kids [ 4 0 R ] 104 | /Count 1 105 | /Type /Pages 106 | >> 107 | endobj 108 | 109 | 6 0 obj 110 | << /Pages 5 0 R 111 | /Type /Catalog 112 | >> 113 | endobj 114 | 115 | xref 116 | 0 7 117 | 0000000000 65535 f 118 | 0000000010 00000 n 119 | 0000000034 00000 n 120 | 0000002801 00000 n 121 | 0000002824 00000 n 122 | 0000002997 00000 n 123 | 0000003071 00000 n 124 | trailer 125 | << /ID [ (some) (id) ] 126 | /Root 6 0 R 127 | /Size 7 128 | >> 129 | startxref 130 | 3130 131 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab1.imageset/Icon.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 2.802734 5.957153 cm 14 | 0.047059 0.047059 0.047059 scn 15 | 7.197025 6.042798 m 16 | 11.197025 6.042798 l 17 | 11.197025 0.042799 l 18 | 15.197025 0.042799 l 19 | 15.749310 0.042799 16.197025 0.490513 16.197025 1.042798 c 20 | 16.197025 8.042798 l 21 | 17.894047 8.042798 l 22 | 18.170189 8.042798 18.394047 8.266656 18.394047 8.542798 c 23 | 18.394047 8.684542 18.333885 8.819624 18.228529 8.914446 c 24 | 9.531507 16.741764 l 25 | 9.341355 16.912901 9.052695 16.912901 8.862543 16.741764 c 26 | 0.165522 8.914446 l 27 | -0.039733 8.729716 -0.056372 8.413570 0.128357 8.208316 c 28 | 0.223178 8.102959 0.358261 8.042798 0.500004 8.042798 c 29 | 2.197025 8.042798 l 30 | 2.197025 1.042798 l 31 | 2.197025 0.490513 2.644740 0.042799 3.197025 0.042799 c 32 | 7.197025 0.042799 l 33 | 7.197025 6.042798 l 34 | h 35 | f 36 | n 37 | Q 38 | 39 | endstream 40 | endobj 41 | 42 | 3 0 obj 43 | 779 44 | endobj 45 | 46 | 4 0 obj 47 | << /Annots [] 48 | /Type /Page 49 | /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] 50 | /Resources 1 0 R 51 | /Contents 2 0 R 52 | /Parent 5 0 R 53 | >> 54 | endobj 55 | 56 | 5 0 obj 57 | << /Kids [ 4 0 R ] 58 | /Count 1 59 | /Type /Pages 60 | >> 61 | endobj 62 | 63 | 6 0 obj 64 | << /Pages 5 0 R 65 | /Type /Catalog 66 | >> 67 | endobj 68 | 69 | xref 70 | 0 7 71 | 0000000000 65535 f 72 | 0000000010 00000 n 73 | 0000000034 00000 n 74 | 0000000869 00000 n 75 | 0000000891 00000 n 76 | 0000001064 00000 n 77 | 0000001138 00000 n 78 | trailer 79 | << /ID [ (some) (id) ] 80 | /Root 6 0 R 81 | /Size 7 82 | >> 83 | startxref 84 | 1197 85 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon (1).pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab2.imageset/Icon (1).pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 3.857422 3.500000 cm 14 | 0.047059 0.047059 0.047059 scn 15 | 8.144285 0.000000 m 16 | 6.451577 0.000000 5.144286 0.875000 5.144286 2.500000 c 17 | 11.144285 2.500000 l 18 | 11.144285 0.875000 9.836993 0.000000 8.144285 0.000000 c 19 | h 20 | 14.138243 7.790353 m 21 | 14.138243 6.076067 16.285713 5.647496 16.285713 4.790354 c 22 | 16.285713 3.933210 15.857142 3.504639 14.142857 3.504639 c 23 | 2.142857 3.504639 l 24 | 0.428571 3.504639 0.000000 3.933210 0.000000 4.790354 c 25 | 0.000000 5.647496 2.142857 6.076067 2.142857 7.790353 c 26 | 2.142857 10.790353 l 27 | 2.142857 15.076067 3.857143 18.642857 7.285715 18.642857 c 28 | 7.285715 19.285715 7.714285 19.500000 8.142857 19.500000 c 29 | 8.571428 19.500000 9.000000 19.285715 9.000000 18.642857 c 30 | 12.428572 18.642857 14.138243 15.076067 14.138243 10.790353 c 31 | 14.138243 7.790353 l 32 | h 33 | f 34 | n 35 | Q 36 | 37 | endstream 38 | endobj 39 | 40 | 3 0 obj 41 | 835 42 | endobj 43 | 44 | 4 0 obj 45 | << /Annots [] 46 | /Type /Page 47 | /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] 48 | /Resources 1 0 R 49 | /Contents 2 0 R 50 | /Parent 5 0 R 51 | >> 52 | endobj 53 | 54 | 5 0 obj 55 | << /Kids [ 4 0 R ] 56 | /Count 1 57 | /Type /Pages 58 | >> 59 | endobj 60 | 61 | 6 0 obj 62 | << /Pages 5 0 R 63 | /Type /Catalog 64 | >> 65 | endobj 66 | 67 | xref 68 | 0 7 69 | 0000000000 65535 f 70 | 0000000010 00000 n 71 | 0000000034 00000 n 72 | 0000000925 00000 n 73 | 0000000947 00000 n 74 | 0000001120 00000 n 75 | 0000001194 00000 n 76 | trailer 77 | << /ID [ (some) (id) ] 78 | /Root 6 0 R 79 | /Size 7 80 | >> 81 | startxref 82 | 1253 83 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "message_24.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab3.imageset/message_24.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 2.500000 4.449921 cm 14 | 0.047059 0.047059 0.047059 scn 15 | 9.250000 18.050079 m 16 | 14.358634 18.050079 18.500000 14.468357 18.500000 10.050079 c 17 | 18.500000 5.631802 14.358634 2.050079 9.250000 2.050079 c 18 | 8.376160 2.050079 7.530620 2.154875 6.729267 2.350729 c 19 | 5.679790 1.416285 3.927846 0.641308 1.475094 0.026514 c 20 | 1.369275 -0.000010 1.257324 0.014830 1.162069 0.068005 c 21 | 0.955449 0.183350 0.881457 0.444355 0.996802 0.650974 c 22 | 1.175095 0.975216 l 23 | 1.962773 2.428423 2.434538 3.603624 2.590388 4.500820 c 24 | 0.985959 5.937621 0.000000 7.894268 0.000000 10.050079 c 25 | 0.000000 14.468357 4.141366 18.050079 9.250000 18.050079 c 26 | h 27 | f 28 | n 29 | Q 30 | 31 | endstream 32 | endobj 33 | 34 | 3 0 obj 35 | 685 36 | endobj 37 | 38 | 4 0 obj 39 | << /Annots [] 40 | /Type /Page 41 | /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] 42 | /Resources 1 0 R 43 | /Contents 2 0 R 44 | /Parent 5 0 R 45 | >> 46 | endobj 47 | 48 | 5 0 obj 49 | << /Kids [ 4 0 R ] 50 | /Count 1 51 | /Type /Pages 52 | >> 53 | endobj 54 | 55 | 6 0 obj 56 | << /Pages 5 0 R 57 | /Type /Catalog 58 | >> 59 | endobj 60 | 61 | xref 62 | 0 7 63 | 0000000000 65535 f 64 | 0000000010 00000 n 65 | 0000000034 00000 n 66 | 0000000775 00000 n 67 | 0000000797 00000 n 68 | 0000000970 00000 n 69 | 0000001044 00000 n 70 | trailer 71 | << /ID [ (some) (id) ] 72 | /Root 6 0 R 73 | /Size 7 74 | >> 75 | startxref 76 | 1103 77 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon (2).pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab4.imageset/Icon (2).pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 2.000000 5.121704 cm 14 | 0.047059 0.047059 0.047059 scn 15 | 10.111005 15.178780 m 16 | 11.238929 16.234959 12.540508 16.808491 13.991766 16.872311 c 17 | 14.265625 16.878296 l 18 | 17.422844 16.878296 20.000000 14.318028 20.000000 11.161065 c 19 | 20.000000 8.202311 18.964657 6.734314 14.426899 3.099865 c 20 | 13.493702 2.360119 l 21 | 11.129551 0.517576 l 22 | 10.465452 0.000000 9.534548 0.000000 8.870449 0.517576 c 23 | 6.182424 2.615273 l 24 | 1.127331 6.609479 0.000000 8.073669 0.000000 11.161065 c 25 | 0.000000 14.318028 2.577156 16.878296 5.734375 16.878296 c 26 | 7.274605 16.878296 8.662557 16.302240 9.872261 15.183285 c 27 | 9.994000 15.065296 l 28 | 10.111005 15.178780 l 29 | h 30 | f 31 | n 32 | Q 33 | 34 | endstream 35 | endobj 36 | 37 | 3 0 obj 38 | 691 39 | endobj 40 | 41 | 4 0 obj 42 | << /Annots [] 43 | /Type /Page 44 | /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] 45 | /Resources 1 0 R 46 | /Contents 2 0 R 47 | /Parent 5 0 R 48 | >> 49 | endobj 50 | 51 | 5 0 obj 52 | << /Kids [ 4 0 R ] 53 | /Count 1 54 | /Type /Pages 55 | >> 56 | endobj 57 | 58 | 6 0 obj 59 | << /Pages 5 0 R 60 | /Type /Catalog 61 | >> 62 | endobj 63 | 64 | xref 65 | 0 7 66 | 0000000000 65535 f 67 | 0000000010 00000 n 68 | 0000000034 00000 n 69 | 0000000781 00000 n 70 | 0000000803 00000 n 71 | 0000000976 00000 n 72 | 0000001050 00000 n 73 | trailer 74 | << /ID [ (some) (id) ] 75 | /Root 6 0 R 76 | /Size 7 77 | >> 78 | startxref 79 | 1109 80 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon (3).pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Assets.xcassets/tab5.imageset/Icon (3).pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 3.000000 4.000000 cm 14 | 0.047059 0.047059 0.047059 scn 15 | 0.000000 6.330433 m 16 | 1.019524 7.776756 2.378987 8.966253 3.962178 9.782715 c 17 | 5.337073 8.667936 7.089035 8.000014 8.996998 8.000014 c 18 | 10.904961 8.000014 12.656922 8.667936 14.031817 9.782715 c 19 | 15.615006 8.966253 16.974470 7.776752 17.993994 6.330430 c 20 | 17.869474 2.818959 13.889052 0.000013 8.996998 0.000013 c 21 | 4.104942 0.000013 0.124517 2.818960 0.000000 6.330433 c 22 | h 23 | f* 24 | n 25 | Q 26 | q 27 | 1.000000 0.000000 -0.000000 1.000000 6.997009 14.000000 cm 28 | 0.047059 0.047059 0.047059 scn 29 | 10.000000 5.000000 m 30 | 10.000000 2.238576 7.761424 0.000000 5.000000 0.000000 c 31 | 2.238576 0.000000 0.000000 2.238576 0.000000 5.000000 c 32 | 0.000000 7.761424 2.238576 10.000000 5.000000 10.000000 c 33 | 7.761424 10.000000 10.000000 7.761424 10.000000 5.000000 c 34 | h 35 | f 36 | n 37 | Q 38 | 39 | endstream 40 | endobj 41 | 42 | 3 0 obj 43 | 843 44 | endobj 45 | 46 | 4 0 obj 47 | << /Annots [] 48 | /Type /Page 49 | /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] 50 | /Resources 1 0 R 51 | /Contents 2 0 R 52 | /Parent 5 0 R 53 | >> 54 | endobj 55 | 56 | 5 0 obj 57 | << /Kids [ 4 0 R ] 58 | /Count 1 59 | /Type /Pages 60 | >> 61 | endobj 62 | 63 | 6 0 obj 64 | << /Pages 5 0 R 65 | /Type /Catalog 66 | >> 67 | endobj 68 | 69 | xref 70 | 0 7 71 | 0000000000 65535 f 72 | 0000000010 00000 n 73 | 0000000034 00000 n 74 | 0000000933 00000 n 75 | 0000000955 00000 n 76 | 0000001128 00000 n 77 | 0000001202 00000 n 78 | trailer 79 | << /ID [ (some) (id) ] 80 | /Root 6 0 R 81 | /Size 7 82 | >> 83 | startxref 84 | 1261 85 | %%EOF -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Example 4 | // 5 | // Created by Alisa Mylnikova on 23.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | import AnimatedTabBar 10 | 11 | struct CircleValues { 12 | var scale = 1.0 13 | var offset = 1.3 14 | } 15 | 16 | struct ContentView: View { 17 | 18 | @State private var selectedIndex = 1 19 | @State private var prevSelectedIndex = 1 20 | 21 | let names = ["heart", "leaf", "drop", "circle", "book"] 22 | 23 | // a hack for keyframe animation 24 | @State var time = 0.0 25 | let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect() 26 | 27 | var body: some View { 28 | #if swift(>=5.9) 29 | if #available(iOS 17.0, *) { 30 | tabbars() 31 | // a hack for keyframe animation 32 | .onReceive(timer) { input in 33 | time = Date().timeIntervalSince1970 34 | } 35 | } else { 36 | tabbars() 37 | } 38 | #else 39 | tabbars() 40 | #endif 41 | } 42 | 43 | func tabbars() -> some View { 44 | ZStack(alignment: .bottom) { 45 | Color.examplePurple.edgesIgnoringSafeArea(.all) 46 | 47 | VStack(spacing: 50) { 48 | AnimatedTabBar(selectedIndex: $selectedIndex, prevSelectedIndex: $prevSelectedIndex) { 49 | colorButtonAt(0, type: .bell) 50 | colorButtonAt(1, type: .bell) 51 | colorButtonAt(2, type: .plus) 52 | colorButtonAt(3, type: .calendar) 53 | colorButtonAt(4, type: .gear) 54 | } 55 | .cornerRadius(16) 56 | .selectedColor(.exampleGrey) 57 | .unselectedColor(.exampleLightGrey) 58 | .ballColor(.white) 59 | .verticalPadding(20) 60 | .ballTrajectory(.straight) 61 | .ballAnimation(.interpolatingSpring(stiffness: 130, damping: 15)) 62 | .indentAnimation(.easeOut(duration: 0.3)) 63 | 64 | AnimatedTabBar(selectedIndex: $selectedIndex, 65 | views: (0..<5).map { dropletButtonAt($0) }) 66 | .cornerRadius(16) 67 | .selectedColor(.exampleGrey.opacity(0.3)) 68 | .unselectedColor(.exampleGrey.opacity(0.3)) 69 | .ballColor(.white) 70 | .verticalPadding(15) 71 | 72 | AnimatedTabBar(selectedIndex: $selectedIndex, 73 | views: (0..=5.9) 82 | if #available(iOS 17.0, *) { 83 | AnimatedTabBar(selectedIndex: $selectedIndex, 84 | views: (0.. some View { 100 | ColorButton( 101 | image: Image("colorTab\(index+1)"), 102 | colorImage: Image("colorTab\(index+1)Bg"), 103 | isSelected: selectedIndex == index, 104 | fromLeft: prevSelectedIndex < index, 105 | toLeft: selectedIndex < index, 106 | animationType: type) 107 | } 108 | 109 | func dropletButtonAt(_ index: Int) -> some View { 110 | DropletButton(imageName: "tab\(index+1)", dropletColor: .examplePurple, isSelected: selectedIndex == index) 111 | } 112 | 113 | func wiggleButtonAt(_ index: Int, name: String) -> some View { 114 | WiggleButton(image: Image(systemName: name), maskImage: Image(systemName: "\(name).fill"), isSelected: index == selectedIndex) 115 | .scaleEffect(1.2) 116 | } 117 | 118 | #if swift(>=5.9) 119 | @available(iOS 17.0, *) 120 | func keyframeWiggleButtonAt(_ index: Int, name: String) -> some View { 121 | KeyframeWiggleButton(image: Image(systemName: name), maskImage: Image(systemName: "\(name).fill"), isSelected: index == selectedIndex) 122 | .scaleEffect(1.2) 123 | } 124 | #endif 125 | } 126 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/ExampleApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleApp.swift 3 | // Example 4 | // 5 | // Created by Alisa Mylnikova on 23.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct ExampleApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/ExampleColorButtons.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleButtons.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 27.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct ColorButton: View { 11 | 12 | public enum AnimationType { 13 | case bell 14 | case plus 15 | case calendar 16 | case gear 17 | } 18 | 19 | public var image: Image 20 | public var colorImage: Image 21 | public var isSelected: Bool 22 | public var fromLeft: Bool 23 | public var toLeft: Bool 24 | public var animationType: AnimationType 25 | 26 | @State var t: CGFloat = 0 27 | @State var tForBg: CGFloat = 0 28 | 29 | var scale: CGFloat { 30 | 1 + t * 0.2 31 | } 32 | 33 | public var body: some View { 34 | ZStack { 35 | ColorButtonBg(colorImage: colorImage, isSelected: isSelected, fromLeft: fromLeft, toLeft: toLeft, t: tForBg) 36 | .offset(x: 3, y: 3) 37 | switch animationType { 38 | case .bell: 39 | ColorButtonOutlineBell(image: image, t: t) 40 | case .plus: 41 | ColorButtonOutlinePlus(image: image, t: t) 42 | case .calendar: 43 | ColorButtonOutlineCalendar(image: image, fromLeft: fromLeft, t: t) 44 | case .gear: 45 | ColorButtonOutlineGear(image: image, t: t) 46 | } 47 | } 48 | .padding(8) 49 | .onAppear { 50 | if isSelected { 51 | tForBg = 1 52 | } 53 | } 54 | .onChange(of: isSelected) { newValue in 55 | if newValue { 56 | withAnimation(.interpolatingSpring(stiffness: 300, damping: 10).delay(0.15)) { 57 | t = 1 58 | } 59 | withAnimation(.easeIn(duration: 0.3)) { 60 | tForBg = 1 61 | } 62 | } else { 63 | t = 0 64 | withAnimation(.easeIn(duration: 0.3)) { 65 | tForBg = 0 66 | } 67 | } 68 | } 69 | } 70 | } 71 | 72 | struct ColorButtonOutlineBell: View, Animatable { 73 | 74 | var image: Image 75 | var t: CGFloat 76 | 77 | nonisolated var animatableData: CGFloat { 78 | get { t } 79 | set { t = newValue } 80 | } 81 | 82 | var angle: CGFloat { 83 | if t < 0.5 { 84 | return 2*t * 20 85 | } 86 | return 2*(1 - t) * 20 87 | } 88 | 89 | var body: some View { 90 | image 91 | .rotationEffect(Angle(degrees: angle), anchor: UnitPoint(x: 0.5, y: 0)) 92 | } 93 | } 94 | 95 | struct ColorButtonOutlinePlus: View { 96 | 97 | var image: Image 98 | var t: CGFloat 99 | 100 | var body: some View { 101 | ZStack { 102 | image 103 | Image("colorTab3Plus") 104 | .rotationEffect(Angle(degrees: t * 90)) 105 | } 106 | } 107 | } 108 | 109 | struct ColorButtonOutlineCalendar: View, Animatable { 110 | 111 | var image: Image 112 | var fromLeft: Bool 113 | var t: CGFloat 114 | 115 | nonisolated var animatableData: CGFloat { 116 | get { t } 117 | set { t = newValue } 118 | } 119 | 120 | var body: some View { 121 | ZStack { 122 | image 123 | .offset(x: offset(maxValue: 5)) 124 | Circle() 125 | .frame(width: 3) 126 | .offset(x: 3, y: 4) 127 | .offset(x: offset(maxValue: 8)) 128 | } 129 | } 130 | 131 | func offset(maxValue: CGFloat) -> CGFloat { 132 | let max = fromLeft ? maxValue : -maxValue 133 | if t < 0.5 { 134 | return 2*t * max 135 | } 136 | return 2*(1 - t) * max 137 | } 138 | } 139 | 140 | struct ColorButtonOutlineGear: View { 141 | 142 | var image: Image 143 | var t: CGFloat 144 | 145 | var body: some View { 146 | image 147 | .rotationEffect(Angle(degrees: t * 50)) 148 | } 149 | } 150 | 151 | struct ColorButtonBg: View { 152 | 153 | var colorImage: Image 154 | var isSelected: Bool 155 | var fromLeft: Bool 156 | var toLeft: Bool 157 | var t: CGFloat 158 | 159 | var offset: CGFloat { 160 | if isSelected { 161 | return fromLeft ? (t - 1) * 20 : (t - 1) * -15 162 | } else { 163 | return toLeft ? (t - 1) * 20 : (t - 1) * -15 164 | } 165 | } 166 | 167 | var body: some View { 168 | colorImage 169 | .scaleEffect(t) 170 | .offset(x: offset) 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIViewControllerBasedStatusBarAppearance 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/KeyframeWiggleButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 14.06.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct AnimationValues { 11 | var growingScale = 1.0 12 | var shrinkingScale = 1.3 13 | var bgWiggle = 0.0 14 | } 15 | 16 | #if swift(>=5.9) 17 | @available(iOS 17.0, *) 18 | public struct KeyframeWiggleButton: View { 19 | 20 | public var image: Image 21 | public var maskImage: Image 22 | public var isSelected: Bool 23 | 24 | @State private var isGrowing = true 25 | 26 | public var body: some View { 27 | image 28 | .keyframeAnimator(initialValue: AnimationValues(), trigger: isSelected) { [isGrowing] content, value in 29 | ZStack { 30 | KeyframeWiggleButtonBg(t: isGrowing ? value.bgWiggle : 0) 31 | .opacity(0.4) 32 | .mask(maskImage) 33 | content 34 | } 35 | .scaleEffect(isGrowing ? value.growingScale : value.shrinkingScale) 36 | } keyframes: { _ in 37 | KeyframeTrack(\.growingScale) { 38 | CubicKeyframe(1.3, duration: 0.1) 39 | CubicKeyframe(1.4, duration: 0.1) 40 | CubicKeyframe(1.3, duration: 0.1) 41 | } 42 | 43 | KeyframeTrack(\.bgWiggle) { 44 | SpringKeyframe(0.0, duration: 0.05) 45 | SpringKeyframe(3.0, duration: 0.1) 46 | SpringKeyframe(1.0, duration: 0.1) 47 | SpringKeyframe(2.0, duration: 0.1) 48 | SpringKeyframe(0.0, duration: 0.1) 49 | } 50 | 51 | KeyframeTrack(\.shrinkingScale) { 52 | SpringKeyframe(0.9, duration: 0.2) 53 | } 54 | } 55 | .onChange(of: isSelected) { oldValue, newValue in 56 | isGrowing = newValue 57 | } 58 | .onAppear { 59 | isGrowing = !isSelected 60 | } 61 | } 62 | } 63 | 64 | struct KeyframeWiggleButtonBg: Shape { 65 | 66 | var t: CGFloat 67 | 68 | func path(in rect: CGRect) -> Path { 69 | var path = Path() 70 | path.addArc(center: CGPoint(x: rect.midX, y: rect.maxY), radius: 10 + t, startAngle: Angle(radians: 0), endAngle: Angle(radians: .pi), clockwise: true) 71 | return path 72 | } 73 | } 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /AnimatedTabBarExample/AnimatedTabBarExample/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // Example 4 | // 5 | // Created by Alisa Mylnikova on 23.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension Color { 11 | init(hex: String) { 12 | let scanner = Scanner(string: hex) 13 | var rgbValue: UInt64 = 0 14 | scanner.scanHexInt64(&rgbValue) 15 | 16 | let r = (rgbValue & 0xff0000) >> 16 17 | let g = (rgbValue & 0xff00) >> 8 18 | let b = rgbValue & 0xff 19 | 20 | self.init(red: Double(r) / 0xff, green: Double(g) / 0xff, blue: Double(b) / 0xff) 21 | } 22 | 23 | static let exampleGrey = Color(hex: "0C0C0C") 24 | static let exampleLightGrey = Color(hex: "B1B1B1") 25 | static let examplePurple = Color(hex: "7D26FE") 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 exyte 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.9 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "AnimatedTabBar", 7 | platforms: [ 8 | .iOS(.v16), 9 | ], 10 | products: [ 11 | .library( 12 | name: "AnimatedTabBar", 13 | targets: ["AnimatedTabBar"]), 14 | ], 15 | dependencies: [], 16 | targets: [ 17 | .target( 18 | name: "AnimatedTabBar", 19 | dependencies: [], 20 | swiftSettings: [ 21 | .enableExperimentalFeature("StrictConcurrency") 22 | ] 23 | ), 24 | ] 25 | ) 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |       4 | 5 | 6 | ![demo](https://user-images.githubusercontent.com/9447630/217482148-8594b3ce-e6be-4e84-a65d-29915566a61a.gif) 7 | 8 |

Animated Tab Bar

9 | 10 |

AnimatedTabBar is a tabbar with a number of preset animations written in pure SwiftUI

11 | 12 | Read Article » 13 | 14 | ![](https://img.shields.io/github/v/tag/exyte/AnimatedTabBar?label=Version) 15 | [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fexyte%2FAnimatedTabBar%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/exyte/AnimatedTabBar) 16 | [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fexyte%2FAnimatedTabBar%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/exyte/AnimatedTabBar) 17 | [![SPM](https://img.shields.io/badge/SPM-Compatible-brightgreen.svg)](https://swiftpackageindex.com/exyte/AnimatedTabBar) 18 | [![Cocoapods](https://img.shields.io/badge/Cocoapods-Deprecated%20after%200.1.4-yellow.svg)](https://cocoapods.org/pods/ExyteAnimatedTabBar) 19 | [![License: MIT](https://img.shields.io/badge/License-MIT-black.svg)](https://opensource.org/licenses/MIT) 20 | 21 | # Usage 22 | 1. Add an `Int` to store the current selection 23 | 2. Pass your buttons to the AnimatedTabBar using one of 2 initializers. For the first one you can pass any view type: 24 | ```swift 25 | import AnimatedTabBar 26 | 27 | AnimatedTabBar(selectedIndex: $selectedIndex) { 28 | TabButton1() 29 | TabButton2() 30 | TabButton3() 31 | } 32 | ``` 33 | 34 | For the second one the views must have the same type, or be manually converted to `AnyView` 35 | ```swift 36 | AnimatedTabBar(selectedIndex: $selectedIndex, views: [TabButton1(), TabButton2(), TabButton3()]) 37 | ``` 38 | 39 | ### Required parameters 40 | `selectedIndex` - binding to the current index 41 | `views` - buttons to display in the tabbar 42 | 43 | ### Available customizations - modifiers 44 | use the `customize` closure in the popup modifier: 45 | 46 | `barColor` - Color of the tabbar itself 47 | `selectedColor` - Selected tab color (use template rendering for this color to be applied properly) 48 | `unselectedColor` - Unselected tab color 49 | `ballColor` - Ball indicator color 50 | `verticalPadding` - Space from the buttons to the bar's top and bottom edges 51 | `cornerRadius` - The corner radius applied to the tabbar background color 52 | `ballAnimation` - Animation curve to apply to ball motion, default is .easeOut(duration: 0.6) 53 | `indentAnimation` - Animation curve for growing/shrinking of the indent in the tabbar 54 | `buttonsAnimation` - Animation curve for applying color to tab buttons 55 | `didSelectIndex` - Closure which gets called on every tab tap 56 | 57 | `ballTrajectory` - Options for ball indicator animation paths: 58 | - `parabolic` - Jump to the selected button following a parabolic arc 59 | - `teleport` - Disappear and quickly re-appear above selected tab 60 | - `straight` - Slide to the selected tab 61 | 62 | ### Built-in animatable tab buttons 63 | By default tabs only have a simple color animation, but you can customize that. This library has two built-in button types you can use out-of-the-box: `DropletButton` and `WiggleButton`, and a super custom `ColorButton` type in the Example project. Please feel free to use them in your projects or build your own buttons on top of them. 64 | 65 | ## Examples 66 | 67 | To try the AnimatedTabBar examples: 68 | - Clone the repo `https://github.com/exyte/AnimatedTabBar.git` 69 | - Open `AnimatedTabBarExample.xcodeproj` in the Xcode 70 | - Try it! 71 | 72 | ## Installation 73 | 74 | ### [Swift Package Manager](https://swift.org/package-manager/) 75 | 76 | ```swift 77 | dependencies: [ 78 | .package(url: "https://github.com/exyte/AnimatedTabBar.git") 79 | ] 80 | ``` 81 | 82 | ## Requirements 83 | 84 | * iOS 16+ 85 | * Xcode 14+ 86 | 87 | ## Acknowledgements 88 | 89 | Many thanks to [Yeasin Arafat](https://dribbble.com/shots/14883627-Tab-Bar-Animation) for their beautiful original work that we recreated with SwiftUI. 90 | 91 | ## Our other open source SwiftUI libraries 92 | [PopupView](https://github.com/exyte/PopupView) - Toasts and popups library 93 | [AnchoredPopup](https://github.com/exyte/AnchoredPopup) - Anchored Popup grows "out" of a trigger view (similar to Hero animation) 94 | [Grid](https://github.com/exyte/Grid) - The most powerful Grid container 95 | [ScalingHeaderScrollView](https://github.com/exyte/ScalingHeaderScrollView) - A scroll view with a sticky header which shrinks as you scroll 96 | [MediaPicker](https://github.com/exyte/mediapicker) - Customizable media picker 97 | [Chat](https://github.com/exyte/chat) - Chat UI framework with fully customizable message cells, input view, and a built-in media picker 98 | [OpenAI](https://github.com/exyte/OpenAI) Wrapper lib for [OpenAI REST API](https://platform.openai.com/docs/api-reference/introduction) 99 | [AnimatedGradient](https://github.com/exyte/AnimatedGradient) - Animated linear gradient 100 | [ConcentricOnboarding](https://github.com/exyte/ConcentricOnboarding) - Animated onboarding flow 101 | [FloatingButton](https://github.com/exyte/FloatingButton) - Floating button menu 102 | [ActivityIndicatorView](https://github.com/exyte/ActivityIndicatorView) - A number of animated loading indicators 103 | [ProgressIndicatorView](https://github.com/exyte/ProgressIndicatorView) - A number of animated progress indicators 104 | [FlagAndCountryCode](https://github.com/exyte/FlagAndCountryCode) - Phone codes and flags for every country 105 | [SVGView](https://github.com/exyte/SVGView) - SVG parser 106 | [LiquidSwipe](https://github.com/exyte/LiquidSwipe) - Liquid navigation animation 107 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnimatedTabBar.h 3 | // AnimatedTabBar 4 | // 5 | // Created by Alisa Mylnikova on 23.01.2023. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for AnimatedTabBar. 11 | FOUNDATION_EXPORT double AnimatedTabBarVersionNumber; 12 | 13 | //! Project version string for AnimatedTabBar. 14 | FOUNDATION_EXPORT const unsigned char AnimatedTabBarVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/AnimatedTabbar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // asd 4 | // 5 | // Created by Alisa Mylnikova on 05/10/2020. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct AnimatedTabBar: View { 11 | 12 | public enum BallTrajectory { 13 | case parabolic 14 | case teleport 15 | case straight 16 | } 17 | 18 | @Binding private var selectedIndex: Int 19 | @Binding private var prevSelectedIndex: Int 20 | private var views: [AnyView] = [] 21 | 22 | public init(selectedIndex: Binding, 23 | prevSelectedIndex: Binding? = nil, 24 | @ViewBuilder content: @escaping () -> TupleView) { 25 | self._selectedIndex = selectedIndex 26 | self._prevSelectedIndex = prevSelectedIndex ?? .constant(0) 27 | self.internalPrevSelectedIndex = selectedIndex.wrappedValue 28 | self.views = content().getViews 29 | } 30 | 31 | public init(selectedIndex: Binding, 32 | prevSelectedIndex: Binding? = nil, 33 | views: [Content]) { 34 | self._selectedIndex = selectedIndex 35 | self._prevSelectedIndex = prevSelectedIndex ?? .constant(0) 36 | self.internalPrevSelectedIndex = selectedIndex.wrappedValue 37 | self.views = views.map { AnyView($0) } 38 | } 39 | 40 | // MARK: - Customization 41 | 42 | private var barColor: Color = .white 43 | private var selectedColor: Color = .red 44 | private var unselectedColor: Color = .black 45 | private var ballColor: Color = .red 46 | 47 | private var verticalPadding: CGFloat = 30 48 | private var cornerRadius: CGFloat = 0 49 | 50 | private var ballAnimation: Animation = .easeOut(duration: 0.6) 51 | private var indentAnimation: Animation = .easeOut(duration: 0.6) 52 | private var buttonsAnimation: Animation = .easeOut(duration: 0.6) 53 | private var ballTrajectory: BallTrajectory = .parabolic 54 | 55 | private var didSelectIndex: ((Int)->())? = nil 56 | 57 | // MARK: - Properties 58 | 59 | @State private var frames: [CGRect] = [] 60 | @State private var tBall: CGFloat = 0 61 | @State private var tIndent: CGFloat = 0 62 | @State private var internalPrevSelectedIndex: Int = 0 63 | 64 | private let circleSize = 10.0 65 | 66 | @Environment(\.layoutDirection) private var layoutDirection 67 | 68 | public var body: some View { 69 | VStack { 70 | HStack(alignment: .bottom) { 71 | if layoutDirection == .rightToLeft { 72 | Spacer() 73 | circle 74 | .scaleEffect(x: layoutDirection == .rightToLeft ? -1 : 1, y: 1) 75 | } else { 76 | circle 77 | Spacer() 78 | } 79 | } 80 | 81 | ZStack { 82 | background 83 | .cornerRadius(cornerRadius) 84 | 85 | ButtonsBar { 86 | ForEach(0..=5.9) 95 | if #available(iOS 17.0, *) { 96 | view.animation(.linear) { 97 | $0.foregroundStyle(selectedIndex == i ? selectedColor : unselectedColor) 98 | } 99 | } else { 100 | view 101 | .foregroundStyle(selectedIndex == i ? selectedColor : unselectedColor) 102 | .animation(buttonsAnimation, value: selectedIndex) 103 | } 104 | #else 105 | view 106 | .foregroundStyle(selectedIndex == i ? selectedColor : unselectedColor) 107 | .animation(buttonsAnimation, value: selectedIndex) 108 | #endif 109 | } 110 | } 111 | .coordinateSpace(name: buttonsBarSpace) 112 | .onPreferenceChange(ButtonPreferenceKey.self) { frames in 113 | DispatchQueue.main.async { 114 | self.frames = frames 115 | } 116 | } 117 | .padding(.vertical, verticalPadding) 118 | } 119 | .fixedSize(horizontal: false, vertical: true) 120 | } 121 | .onChange(of: selectedIndex) { [selectedIndex] newValue in 122 | internalPrevSelectedIndex = selectedIndex 123 | tBall = 0 124 | tIndent = 0 125 | DispatchQueue.main.async { 126 | withAnimation(ballAnimation) { 127 | tBall = 1 128 | } 129 | withAnimation(indentAnimation) { 130 | tIndent = 1 131 | } 132 | } 133 | } 134 | } 135 | 136 | @ViewBuilder 137 | var circle: some View { 138 | switch ballTrajectory { 139 | case .parabolic: 140 | Circle() 141 | .frame(width: circleSize, height: circleSize) 142 | .foregroundColor(ballColor) 143 | .fixedSize() 144 | .alongPath( 145 | t: tBall, 146 | trajectory: trajectory( 147 | from: getBallCoord(internalPrevSelectedIndex), 148 | to: getBallCoord(selectedIndex) 149 | ) 150 | ) 151 | 152 | case .teleport: 153 | Circle() 154 | .frame(width: circleSize, height: circleSize) 155 | .foregroundColor(ballColor) 156 | .fixedSize() 157 | .teleportEffect(t: tBall, from: getBallCoord(internalPrevSelectedIndex).x, to: getBallCoord(selectedIndex).x) 158 | .offset(y: 15) 159 | 160 | case .straight: 161 | Circle() 162 | .frame(width: circleSize, height: circleSize) 163 | .foregroundColor(ballColor) 164 | .fixedSize() 165 | .offset(x: getBallCoord(selectedIndex).x, y: 15) 166 | .animation(ballAnimation, value: selectedIndex) 167 | } 168 | } 169 | 170 | @ViewBuilder 171 | var background: some View { 172 | if let _ = frames[safe: selectedIndex] { 173 | switch ballTrajectory { 174 | case .parabolic, .teleport: 175 | HStack(spacing: 0) { 176 | ForEach(0.. CGPoint { 191 | guard let frame = frames[safe: at] else { 192 | return .zero 193 | } 194 | return CGPoint(x: frame.midX - circleSize/2, y: frame.minY + 15) 195 | } 196 | 197 | func getCoord(_ at: Int) -> CGPoint { 198 | guard let frame = frames[safe: at] else { 199 | return .zero 200 | } 201 | return CGPoint(x: frame.midX, y: frame.minY) 202 | } 203 | 204 | func trajectory(from: CGPoint?, to: CGPoint?) -> Path { 205 | var path = Path() 206 | guard let from = from, let to = to else { 207 | return path 208 | } 209 | path.move(to: from) 210 | path.addQuadCurve(to: to, control: CGPoint(x: (from.x + to.x)/2, y: from.y - 100)) 211 | return path 212 | } 213 | 214 | // MARK: - Customization setters 215 | 216 | public func barColor(_ color: Color) -> AnimatedTabBar { 217 | var switcher = self 218 | switcher.barColor = color 219 | return switcher 220 | } 221 | 222 | public func selectedColor(_ color: Color) -> AnimatedTabBar { 223 | var switcher = self 224 | switcher.selectedColor = color 225 | return switcher 226 | } 227 | 228 | public func unselectedColor(_ color: Color) -> AnimatedTabBar { 229 | var switcher = self 230 | switcher.unselectedColor = color 231 | return switcher 232 | } 233 | 234 | public func ballColor(_ color: Color) -> AnimatedTabBar { 235 | var switcher = self 236 | switcher.ballColor = color 237 | return switcher 238 | } 239 | 240 | public func verticalPadding(_ verticalPadding: CGFloat) -> AnimatedTabBar { 241 | var switcher = self 242 | switcher.verticalPadding = verticalPadding 243 | return switcher 244 | } 245 | 246 | public func cornerRadius(_ cornerRadius: CGFloat) -> AnimatedTabBar { 247 | var switcher = self 248 | switcher.cornerRadius = cornerRadius 249 | return switcher 250 | } 251 | 252 | public func ballAnimation(_ ballAnimation: Animation) -> AnimatedTabBar { 253 | var switcher = self 254 | switcher.ballAnimation = ballAnimation 255 | return switcher 256 | } 257 | 258 | public func indentAnimation(_ indentAnimation: Animation) -> AnimatedTabBar { 259 | var switcher = self 260 | switcher.indentAnimation = indentAnimation 261 | return switcher 262 | } 263 | 264 | public func buttonsAnimation(_ buttonsAnimation: Animation) -> AnimatedTabBar { 265 | var switcher = self 266 | switcher.buttonsAnimation = buttonsAnimation 267 | return switcher 268 | } 269 | 270 | public func ballTrajectory(_ ballTrajectory: BallTrajectory) -> AnimatedTabBar { 271 | var switcher = self 272 | switcher.ballTrajectory = ballTrajectory 273 | return switcher 274 | } 275 | 276 | public func didSelectIndex(_ closure: @escaping (Int)->()) -> AnimatedTabBar { 277 | var switcher = self 278 | switcher.didSelectIndex = closure 279 | return switcher 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/BezierPathLength.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BezierPathLength.swift 3 | // FloatingButton 4 | // 5 | // Created by Alisa Mylnikova on 27/11/2019. 6 | // Copyright © 2019 Exyte. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | extension Path { 12 | 13 | /// Length of path in pt 14 | public var length: CGFloat { 15 | cgPath.length 16 | } 17 | 18 | /// Get the point on the path at the given percentage 19 | /// 20 | /// - Parameter percent: Percentage of path, between 0.0 and 1.0 (can be outside) 21 | /// - Returns: Point on the path 22 | public func point(at percent: CGFloat) -> CGPoint? { 23 | cgPath.point(at: percent) 24 | } 25 | 26 | } 27 | 28 | public extension CGPath { 29 | 30 | typealias PathApplier = @convention(block) (UnsafePointer) -> Void 31 | 32 | func apply(with applier: @escaping PathApplier) { 33 | 34 | let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer) -> Void = { (info, element) in 35 | let block = unsafeBitCast(info, to: PathApplier.self) 36 | block(element) 37 | } 38 | 39 | self.apply(info: unsafeBitCast(applier, to: UnsafeMutableRawPointer.self), function: unsafeBitCast(callback, to: CGPathApplierFunction.self)) 40 | } 41 | 42 | internal var elements: [PathElement] { 43 | var pathElements = [PathElement]() 44 | apply { (element) in 45 | let pathElement = PathElement(element: element.pointee) 46 | pathElements.append(pathElement) 47 | } 48 | return pathElements 49 | } 50 | 51 | /// Length of path in pt 52 | var length: CGFloat { 53 | getLength(with: elements) 54 | } 55 | 56 | /// Get the point on the path at the given percentage 57 | /// 58 | /// - Parameter percent: Percentage of path, between 0.0 and 1.0 (inclusive) 59 | /// - Returns: Point on the path 60 | func point(at percent: CGFloat) -> CGPoint? { 61 | point(at: percent, with: elements) 62 | } 63 | 64 | } 65 | 66 | extension CGPath { 67 | 68 | // MARK: - Internal 69 | 70 | func point(at percent: CGFloat, with elements: [PathElement]) -> CGPoint? { 71 | 72 | let percentLength = length * percent 73 | var lengthTraversed: CGFloat = 0 74 | var firstPointInSubpath: CGPoint? 75 | 76 | /// Holds current point on the path (must never be a control point) 77 | var currentPoint: CGPoint? 78 | 79 | for e in elements { 80 | switch(e) { 81 | case let .move(to: p0): 82 | currentPoint = p0 83 | if firstPointInSubpath == nil { 84 | firstPointInSubpath = p0 85 | } 86 | break 87 | 88 | case let .addLine(to: p1): 89 | guard let p0 = currentPoint else { 90 | assert(false, "Expected current point") 91 | break 92 | } 93 | let l = linearLength(p0: p0, p1: p1) 94 | if lengthTraversed + l >= percentLength || lengthTraversed + l == length { 95 | let lengthInSubpath = percentLength - lengthTraversed; 96 | let t = lengthInSubpath / l 97 | return linearPoint(t: t, p0: p0, p1: p1) 98 | } 99 | lengthTraversed += l 100 | currentPoint = p1 101 | break 102 | 103 | case let .addQuadCurve(c1, to: p1): 104 | guard let p0 = currentPoint else { 105 | assert(false, "Expected current point") 106 | break 107 | } 108 | let l = quadCurveLength(p0: p0, c1: c1, p1: p1) 109 | if lengthTraversed + l >= percentLength || lengthTraversed + l == length { 110 | let lengthInSubpath = percentLength - lengthTraversed 111 | let t = lengthInSubpath / l 112 | return quadCurvePoint(t: t, p0: p0, c1: c1, p1: p1) 113 | } 114 | lengthTraversed += l 115 | currentPoint = p1 116 | break 117 | 118 | case let .addCurve(c1, c2, to: p1): 119 | guard let p0 = currentPoint else { 120 | assert(false, "Expected current point") 121 | break 122 | } 123 | let l = cubicCurveLength(p0: p0, c1: c1, c2: c2, p1: p1) 124 | if lengthTraversed + l >= percentLength || lengthTraversed + l == length { 125 | let lengthInSubpath = percentLength - lengthTraversed 126 | let t = lengthInSubpath / l 127 | return cubicCurvePoint(t: t, p0: p0, c1: c1, c2: c2, p1: p1) 128 | } 129 | lengthTraversed += l 130 | currentPoint = p1 131 | break 132 | 133 | case .closeSubpath: 134 | guard let p0 = currentPoint else { 135 | break 136 | } 137 | if let p1 = firstPointInSubpath { 138 | let l = linearLength(p0: p0, p1: p1) 139 | if lengthTraversed + l >= percentLength || lengthTraversed + l == length { 140 | let lengthInSubpath = percentLength - lengthTraversed; 141 | let t = lengthInSubpath / l 142 | return linearPoint(t: t, p0: p0, p1: p1) 143 | } 144 | lengthTraversed += l 145 | currentPoint = p1 146 | } 147 | firstPointInSubpath = nil 148 | break 149 | } 150 | } 151 | 152 | return nil 153 | } 154 | 155 | func getLength(with elements: [PathElement]) -> CGFloat { 156 | 157 | var firstPointInSubpath: CGPoint? 158 | var length: CGFloat = 0 159 | 160 | /// Holds current point on the path (must never be a control point) 161 | var currentPoint: CGPoint? 162 | 163 | for e in elements { 164 | switch(e) { 165 | case let .move(to: p0): 166 | currentPoint = p0 167 | if firstPointInSubpath == nil { 168 | firstPointInSubpath = p0 169 | } 170 | break 171 | 172 | case let .addLine(to: p1): 173 | guard let p0 = currentPoint else { 174 | assert(false, "Expected current point") 175 | break 176 | } 177 | length += linearLength(p0: p0, p1: p1) 178 | currentPoint = p1 179 | break 180 | 181 | case let .addQuadCurve(c1, to: p1): 182 | guard let p0 = currentPoint else { 183 | assert(false, "Expected current point") 184 | break 185 | } 186 | length += quadCurveLength(p0: p0, c1: c1, p1: p1) 187 | currentPoint = p1 188 | break 189 | 190 | case let .addCurve(c1, c2, to: p1): 191 | guard let p0 = currentPoint else { 192 | assert(false, "Expected current point") 193 | break 194 | } 195 | length += cubicCurveLength(p0: p0, c1: c1, c2: c2, p1: p1) 196 | currentPoint = p1 197 | break 198 | 199 | case .closeSubpath: 200 | guard let p0 = currentPoint else { 201 | break 202 | } 203 | if let p1 = firstPointInSubpath { 204 | length += linearLength(p0: p0, p1: p1) 205 | currentPoint = p1 206 | } 207 | firstPointInSubpath = nil 208 | break 209 | } 210 | } 211 | 212 | return length 213 | 214 | } 215 | 216 | // MARK: - Linear 217 | 218 | func linearLength(p0: CGPoint, p1: CGPoint) -> CGFloat { 219 | p0.distance(to: p1) 220 | } 221 | 222 | func linearPoint(t: CGFloat, p0: CGPoint, p1: CGPoint) -> CGPoint { 223 | let x = linearValue(t: t, p0: p0.x, p1: p1.x) 224 | let y = linearValue(t: t, p0: p0.y, p1: p1.y) 225 | return CGPoint(x: x, y: y) 226 | } 227 | 228 | func linearValue(t: CGFloat, p0: CGFloat, p1: CGFloat) -> CGFloat { 229 | var value: CGFloat = 0.0 230 | // (1-t) * p0 + t * p1 231 | value += (1-t) * p0 232 | value += t * p1 233 | return value 234 | } 235 | 236 | // MARK: - Quadratic 237 | 238 | func quadCurveLength(p0: CGPoint, c1: CGPoint, p1: CGPoint) -> CGFloat { 239 | 240 | var approxDist: CGFloat = 0 241 | let approxSteps: CGFloat = 100 242 | 243 | for i in 0.. CGPoint { 257 | let x = quadCurveValue(t: t, p0: p0.x, c1: c1.x, p1: p1.x) 258 | let y = quadCurveValue(t: t, p0: p0.y, c1: c1.y, p1: p1.y) 259 | return CGPoint(x: x, y: y) 260 | } 261 | 262 | func quadCurveValue(t: CGFloat, p0: CGFloat, c1: CGFloat, p1: CGFloat) -> CGFloat { 263 | var value: CGFloat = 0.0 264 | // (1-t)^2 * p0 + 2 * (1-t) * t * c1 + t^2 * p1 265 | value += pow(1-t, 2) * p0 266 | value += 2 * (1-t) * t * c1 267 | value += pow(t, 2) * p1 268 | return value 269 | } 270 | 271 | // MARK: - Cubic 272 | 273 | func cubicCurveLength(p0: CGPoint, c1: CGPoint, c2: CGPoint, p1: CGPoint) -> CGFloat { 274 | 275 | var approxDist: CGFloat = 0 276 | let approxSteps: CGFloat = 100 277 | 278 | for i in 0.. CGPoint { 293 | let x = cubicCurveValue(t: t, p0: p0.x, c1: c1.x, c2: c2.x, p1: p1.x) 294 | let y = cubicCurveValue(t: t, p0: p0.y, c1: c1.y, c2: c2.y, p1: p1.y) 295 | return CGPoint(x: x, y: y) 296 | } 297 | 298 | func cubicCurveValue(t: CGFloat, p0: CGFloat, c1: CGFloat, c2: CGFloat, p1: CGFloat) -> CGFloat { 299 | var value: CGFloat = 0.0 300 | 301 | // (1-t)^3 * p0 + 3 * (1-t)^2 * t * c1 + 3 * (1-t) * t^2 * c2 + t^3 * p1 302 | value += pow(1-t, 3) * p0 303 | value += 3 * pow(1-t, 2) * t * c1 304 | value += 3 * (1-t) * pow(t, 2) * c2 305 | value += pow(t, 3) * p1 306 | 307 | return value 308 | } 309 | 310 | } 311 | 312 | extension CGPoint { 313 | 314 | func distance(to point: CGPoint) -> CGFloat { 315 | let a = self 316 | let b = point 317 | return sqrt(pow(a.x-b.x, 2) + pow(a.y-b.y, 2)) 318 | } 319 | } 320 | 321 | /// Swifty version of `CGPathElement` & `CGPathElementType` 322 | enum PathElement { 323 | 324 | /// The path element that starts a new subpath. The element holds a single point for the destination. 325 | case move(to: CGPoint) 326 | 327 | /// The path element that adds a line from the current point to a new point. The element holds a single point for the destination. 328 | case addLine(to: CGPoint) 329 | 330 | /// The path element that adds a quadratic curve from the current point to the specified point. The element holds a control point and a destination point. 331 | case addQuadCurve(CGPoint, to: CGPoint) 332 | 333 | /// The path element that adds a cubic curve from the current point to the specified point. The element holds two control points and a destination point. 334 | case addCurve(CGPoint, CGPoint, to: CGPoint) 335 | 336 | /// The path element that closes and completes a subpath. The element does not contain any points. 337 | case closeSubpath 338 | 339 | init(element: CGPathElement) { 340 | switch element.type { 341 | case .moveToPoint: 342 | self = .move(to: element.points[0]) 343 | case .addLineToPoint: 344 | self = .addLine(to: element.points[0]) 345 | case .addQuadCurveToPoint: 346 | self = .addQuadCurve(element.points[0], to: element.points[1]) 347 | case .addCurveToPoint: 348 | self = .addCurve(element.points[0], element.points[1], to: element.points[2]) 349 | case .closeSubpath: 350 | self = .closeSubpath 351 | @unknown default: 352 | fatalError() 353 | } 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/ButtonsBarLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonsBarLayout.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 26.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | let buttonsBarSpace = "ButtonsBarSpace" 11 | 12 | struct ButtonsBar: Layout { 13 | 14 | func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize { 15 | let idealViewSizes = subviews.map { $0.sizeThatFits(.unspecified) } 16 | let height = idealViewSizes.reduce(0) { max($0, $1.height) } 17 | 18 | return CGSize(width: proposal.width ?? 0, height: height) 19 | } 20 | 21 | func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) { 22 | var pt = CGPoint(x: bounds.minX, y: bounds.minY) 23 | let widthDelta = bounds.width / CGFloat(subviews.count) 24 | 25 | for v in subviews { 26 | let idealViewSize = v.sizeThatFits(.unspecified) 27 | let x = pt.x + widthDelta/2 - idealViewSize.width/2 28 | let y = bounds.midY - idealViewSize.height/2 29 | let point = CGPoint(x: x, y: y) 30 | 31 | v.place(at: point, anchor: .topLeading, proposal: .unspecified) 32 | 33 | pt.x += widthDelta 34 | } 35 | } 36 | } 37 | 38 | struct ButtonPreferenceKey: PreferenceKey { 39 | typealias Value = [CGRect] 40 | 41 | static let defaultValue: Value = [] 42 | 43 | static func reduce(value: inout Value, nextValue: () -> Value) { 44 | value.append(contentsOf: nextValue()) 45 | } 46 | } 47 | 48 | struct ButtonPreferenceViewSetter: View { 49 | 50 | var body: some View { 51 | GeometryReader { geometry in 52 | Rectangle() 53 | .fill(Color.clear) 54 | .preference(key: ButtonPreferenceKey.self, 55 | value: [geometry.frame(in: .named(buttonsBarSpace))]) 56 | } 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/GeometryEffects.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeometryEffect.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 24.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct AlongPath: GeometryEffect { 11 | 12 | var t: CGFloat 13 | var trajectory: Path 14 | 15 | var animatableData: CGFloat { 16 | get { t } 17 | set { t = newValue } 18 | } 19 | 20 | public func effectValue(size: CGSize) -> ProjectionTransform { 21 | if let point = trajectory.point(at: t) { 22 | return ProjectionTransform(CGAffineTransform(translationX: point.x, y: point.y)) 23 | } 24 | return ProjectionTransform() 25 | } 26 | } 27 | 28 | extension View { 29 | public func alongPath(t: CGFloat, trajectory: Path) -> some View { 30 | self.modifier(AlongPath(t: t, trajectory: trajectory)) 31 | } 32 | } 33 | 34 | struct TeleportEffect: GeometryEffect { 35 | 36 | var t: CGFloat 37 | var from: CGFloat 38 | var to: CGFloat 39 | 40 | // fraction of full animation time in which animation should happen 41 | var fraction: CGFloat = 0.2 42 | 43 | var animatableData: CGFloat { 44 | get { t } 45 | set { t = newValue } 46 | } 47 | 48 | var scale: CGFloat { 49 | if t < fraction { // 0...0.1 -> 1...0 50 | return 1 - t*1/fraction 51 | } 52 | if t > 1 - fraction { // 0.9...1 -> 0...1 53 | return (t - (1-fraction)) * 1/fraction 54 | } 55 | return -5000 56 | } 57 | 58 | var anchor: CGFloat { 59 | t < 0.5 ? t*2 : (1-t)*2 60 | } 61 | 62 | public func effectValue(size: CGSize) -> ProjectionTransform { 63 | ProjectionTransform(CGAffineTransform(translationX: t < 0.5 ? from : to, y: 0) 64 | .translatedBy(x: size.width * anchor, y: size.height * anchor) 65 | .scaledBy(x: scale, y: scale)) 66 | } 67 | } 68 | 69 | extension View { 70 | public func teleportEffect(t: CGFloat, from: CGFloat, to: CGFloat) -> some View { 71 | self.modifier(TeleportEffect(t: t, from: from, to: to)) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/IndentableRect.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndentableRect.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 24.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct IndentableRect: Shape { 11 | 12 | var t: CGFloat 13 | 14 | // when animating 0 -> 1: do nothing until delay, then animate quickly from delay to 1 15 | // when animating 1 -> 0: animate quickly 1 to delay, then do nothing from delay to 0 16 | var delay: CGFloat = 0 17 | 18 | var animatableData: CGFloat { 19 | get { t } 20 | set { t = newValue } 21 | } 22 | 23 | func path(in rect: CGRect) -> Path { 24 | var t = t 25 | if t < delay { 26 | t = 0 27 | } else { 28 | t = (t - delay) * 1/(1-delay) 29 | } 30 | 31 | let tl = rect.origin 32 | let tr = CGPoint(x: rect.maxX, y: rect.minY) 33 | let bl = CGPoint(x: rect.minX, y: rect.maxY) 34 | let br = CGPoint(x: rect.maxX, y: rect.maxY) 35 | 36 | let yCurve = t * 15 37 | let indentWidth = 60.0 38 | 39 | let indentPath = TranslatedPath(rect: CGRect( 40 | x: rect.midX - indentWidth/2, 41 | y: rect.minY, 42 | width: indentWidth, 43 | height: yCurve) 44 | ).path() 45 | 46 | var path = Path() 47 | path.move(to: tl) 48 | path.addPath(indentPath) 49 | path.addLine(to: tr) 50 | path.addLine(to: br) 51 | path.addLine(to: bl) 52 | path.addLine(to: tl) 53 | return path 54 | } 55 | } 56 | 57 | struct TranslatedPath { 58 | 59 | // svg path 60 | // M 0 0 61 | // C 11.5 0 19.5 17 27.5 17 62 | // C 35.5 17 43.5 0 55 0 63 | 64 | let maxX = 55.0 65 | let maxY = 17.0 66 | 67 | let rect: CGRect 68 | 69 | func translate(x: CGFloat, y: CGFloat) -> CGPoint { 70 | CGPoint(x: x / maxX * rect.width + rect.minX, y: y / maxY * rect.height + rect.minY) 71 | } 72 | 73 | func path() -> Path { 74 | 75 | let t1 = translate(x: 0, y: 0) 76 | let t2 = translate(x: 27.5, y: 17) 77 | let t3 = translate(x: 55, y: 0) 78 | 79 | let c1 = translate(x: 11.5, y: 0) 80 | let c2 = translate(x: 19.5, y: 17) 81 | let c3 = translate(x: 35.5, y: 17) 82 | let c4 = translate(x: 43.5, y: 0) 83 | 84 | var path = Path() 85 | path.move(to: t1) 86 | path.addCurve(to: t2, control1: c1, control2: c2) 87 | path.addCurve(to: t3, control1: c3, control2: c4) 88 | return path 89 | } 90 | } 91 | 92 | struct SlidingIndentRect: Shape { 93 | 94 | var t: CGFloat 95 | 96 | var indentX: CGFloat 97 | var prevIndentX: CGFloat 98 | 99 | var animatableData: CGFloat { 100 | get { t } 101 | set { t = newValue } 102 | } 103 | 104 | func path(in rect: CGRect) -> Path { 105 | let tl = rect.origin 106 | let tr = CGPoint(x: rect.maxX, y: rect.minY) 107 | let bl = CGPoint(x: rect.minX, y: rect.maxY) 108 | let br = CGPoint(x: rect.maxX, y: rect.maxY) 109 | 110 | let indentWidth = 60.0 111 | 112 | let indentPath = TranslatedPath(rect: CGRect( 113 | x: prevIndentX + (indentX - prevIndentX) * t - indentWidth/2, 114 | y: rect.minY, 115 | width: indentWidth, 116 | height: 15) 117 | ).path() 118 | 119 | var path = Path() 120 | path.move(to: tl) 121 | path.addPath(indentPath) 122 | path.addLine(to: tr) 123 | path.addLine(to: br) 124 | path.addLine(to: bl) 125 | path.addLine(to: tl) 126 | return path 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/TabBarButtons/DropletButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIView.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 24.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct DropletButton: View { 11 | 12 | public var imageName: String 13 | public var dropletColor: Color 14 | public var isSelected: Bool 15 | 16 | public init(imageName: String, dropletColor: Color, isSelected: Bool) { 17 | self.imageName = imageName 18 | self.dropletColor = dropletColor 19 | self.isSelected = isSelected 20 | } 21 | 22 | @State var t: CGFloat = 0 23 | 24 | public var body: some View { 25 | DropletButtonAnimatable(imageName: imageName, dropletColor: dropletColor, t: t) 26 | .onChange(of: isSelected) { newValue in 27 | if newValue { 28 | withAnimation(.linear(duration: 0.9)) { 29 | t = 1 30 | } 31 | } else { 32 | t = 0 33 | } 34 | } 35 | .onAppear { 36 | if isSelected { 37 | t = 1 38 | } 39 | } 40 | } 41 | } 42 | 43 | struct DropletButtonAnimatable: View, Animatable { 44 | 45 | var imageName: String 46 | var dropletColor: Color 47 | var t: CGFloat 48 | 49 | public init(imageName: String, dropletColor: Color, t: CGFloat) { 50 | self.imageName = imageName 51 | self.dropletColor = dropletColor 52 | self.t = t 53 | } 54 | 55 | nonisolated public var animatableData: CGFloat { 56 | get { t } 57 | set { t = newValue } 58 | } 59 | 60 | @State private var frame: CGRect = .zero 61 | 62 | private var scale: CGFloat { 63 | var t = t 64 | if t < 0.3 { // 0...0.3 -> 0...1 65 | t = t*3.33 66 | } else { // 0.3...0.6 -> 1...0; 0.6...1 -> 0 67 | t = max((0.6 - t) * 3.33, 0) 68 | } 69 | return 1 - 0.2 * t 70 | } 71 | 72 | private var dropletParam: CGFloat { 73 | if t < 0.3 { 74 | return 0 75 | } else { 76 | return (t - 0.3) * 1/0.7 77 | } 78 | } 79 | 80 | public var body: some View { 81 | ZStack { 82 | Image(imageName) 83 | .padding(.vertical, 10) 84 | Droplet(t: dropletParam) 85 | .mask(t > 0.5 ? AnyView(Image(imageName)) : AnyView(Rectangle().frame(width: frame.width, height: frame.height))) 86 | .foregroundColor(dropletColor) 87 | } 88 | .scaleEffect(scale) 89 | .frameGetter($frame) 90 | } 91 | } 92 | 93 | struct Droplet: Shape { 94 | 95 | var t: CGFloat 96 | 97 | func path(in rect: CGRect) -> Path { 98 | let param = t * 20 99 | let inset = min(t * 5, 1) * 15 100 | 101 | var path = Path() 102 | path.addArc(center: CGPoint(x: rect.midX, y: rect.minY + inset), radius: param, startAngle: Angle(radians: 0), endAngle: Angle(radians: 2 * .pi), clockwise: false) 103 | return path 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/TabBarButtons/WiggleButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIView.swift 3 | // 4 | // 5 | // Created by Alisa Mylnikova on 24.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public struct WiggleButton: View { 11 | 12 | public var image: Image 13 | public var maskImage: Image 14 | public var imageSize: CGFloat 15 | public var isSelected: Bool 16 | 17 | public init(image: Image, maskImage: Image, imageSize: CGFloat? = nil, isSelected: Bool) { 18 | self.image = image 19 | self.maskImage = maskImage 20 | self.imageSize = imageSize ?? 20 21 | self.isSelected = isSelected 22 | } 23 | 24 | @State var t: CGFloat = 0 25 | @State var tForBg: CGFloat = 0 26 | 27 | var scale: CGFloat { 28 | 1 + t * 0.2 29 | } 30 | 31 | public var body: some View { 32 | ZStack { 33 | WiggleButtonBg(t: tForBg) 34 | .opacity(0.4) 35 | .mask( 36 | maskImage 37 | .imageResizer(imageSize) 38 | ) 39 | image 40 | .imageResizer(imageSize) 41 | } 42 | .scaleEffect(scale) 43 | .onChange(of: isSelected) { newValue in 44 | if newValue { 45 | withAnimation(.interpolatingSpring(stiffness: 300, damping: 5)) { 46 | tForBg = 1 47 | } 48 | withAnimation { 49 | t = 1 50 | } 51 | } else { 52 | tForBg = 0 53 | withAnimation { 54 | t = 0 55 | } 56 | } 57 | } 58 | .onAppear { 59 | if isSelected { 60 | t = 1 61 | } 62 | } 63 | } 64 | } 65 | 66 | struct WiggleButtonBg: Shape { 67 | 68 | var t: CGFloat 69 | 70 | var animatableData: CGFloat { 71 | get { t } 72 | set { t = newValue } 73 | } 74 | 75 | func path(in rect: CGRect) -> Path { 76 | var t = t 77 | if t < 0.5 { 78 | t = t*2 79 | } else { 80 | t = (1 - t)*2 81 | } 82 | 83 | let param = t * 2 84 | var path = Path() 85 | path.addArc(center: CGPoint(x: rect.midX, y: rect.maxY), radius: 10 + param, startAngle: Angle(radians: 0), endAngle: Angle(radians: .pi), clockwise: true) 86 | return path 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Sources/AnimatedTabBar/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // AnimatedTabBar 4 | // 5 | // Created by Alisa Mylnikova on 23.01.2023. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension TupleView { 11 | var getViews: [AnyView] { 12 | makeArray(from: value) 13 | } 14 | 15 | private struct GenericView { 16 | let body: Any 17 | 18 | var anyView: AnyView? { 19 | AnyView(_fromValue: body) 20 | } 21 | } 22 | 23 | private func makeArray(from tuple: Tuple) -> [AnyView] { 24 | func convert(child: Mirror.Child) -> AnyView? { 25 | withUnsafeBytes(of: child.value) { ptr -> AnyView? in 26 | let binded = ptr.bindMemory(to: GenericView.self) 27 | return binded.first?.anyView 28 | } 29 | } 30 | 31 | let tupleMirror = Mirror(reflecting: tuple) 32 | return tupleMirror.children.compactMap(convert) 33 | } 34 | } 35 | 36 | extension Collection { 37 | /// Returns the element at the specified index if it is within bounds, otherwise nil. 38 | subscript (safe index: Index) -> Element? { 39 | return indices.contains(index) ? self[index] : nil 40 | } 41 | } 42 | 43 | struct FrameGetter: ViewModifier { 44 | 45 | @Binding var frame: CGRect 46 | 47 | func body(content: Content) -> some View { 48 | content 49 | .background( 50 | GeometryReader { proxy -> AnyView in 51 | DispatchQueue.main.async { 52 | let rect = proxy.frame(in: .global) 53 | // This avoids an infinite layout loop 54 | if rect.integral != self.frame.integral { 55 | self.frame = rect 56 | } 57 | } 58 | return AnyView(EmptyView()) 59 | } 60 | ) 61 | } 62 | } 63 | 64 | extension View { 65 | public func frameGetter(_ frame: Binding) -> some View { 66 | modifier(FrameGetter(frame: frame)) 67 | } 68 | } 69 | 70 | extension Image { 71 | func imageResizer(_ size: CGFloat) -> some View { 72 | self 73 | .resizable() 74 | .aspectRatio(contentMode: .fit) 75 | .frame(width: size, height: size) 76 | } 77 | } 78 | --------------------------------------------------------------------------------