├── README.md ├── TableViewHeaderAnimation.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── as_one.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── xuelin.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── as_one.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ └── xcschememanagement.plist │ └── xuelin.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── TableViewHeaderAnimation.xcscheme │ └── xcschememanagement.plist └── TableViewHeaderAnimation ├── AnimationViewController.swift ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ ├── Icon-1024.png │ ├── Icon-120.png │ ├── Icon-121.png │ ├── Icon-180.png │ ├── Icon-40.png │ ├── Icon-58.png │ ├── Icon-60.png │ ├── Icon-80.png │ └── Icon-87.png ├── Contents.json ├── b.imageset │ ├── Contents.json │ └── b.png └── phil.imageset │ ├── Contents.json │ └── phil.png ├── Base.lproj └── LaunchScreen.storyboard ├── HeaderAnimationTableView.swift ├── Info.plist ├── TableViewCell.swift ├── TableViewCell.xib └── WeChat.gif /README.md: -------------------------------------------------------------------------------- 1 | # SDTableViewHeaderAnimation 2 | 3 | Most tableViewHeader animation has been include in this demo, you can use it inherit the HeaderAnimationTableView. demo中包含了大部分经常用到的tableViewHeader的动画效果,包括:tableViewHeader下拉跟随、放大、折叠效果等。另外,结合另一个[SDDemo](https://github.com/xlsd/SDDemo),可以让更好的理解TableView. 4 | 5 | ![image](https://github.com/xlsd/SDTableViewHeaderAnimation/blob/master/TableViewHeaderAnimation/WeChat.gif) 6 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9A1F95DA1EC5B741008617DE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1F95D91EC5B741008617DE /* AppDelegate.swift */; }; 11 | 9A1F95E11EC5B741008617DE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A1F95E01EC5B741008617DE /* Assets.xcassets */; }; 12 | 9A1F95E41EC5B741008617DE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A1F95E21EC5B741008617DE /* LaunchScreen.storyboard */; }; 13 | 9A92B9ED1EC6987300BA7EF4 /* AnimationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A92B9EC1EC6987300BA7EF4 /* AnimationViewController.swift */; }; 14 | 9A92B9F11EC6AAB100BA7EF4 /* HeaderAnimationTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A92B9F01EC6AAB100BA7EF4 /* HeaderAnimationTableView.swift */; }; 15 | 9A92B9F41EC6B90100BA7EF4 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A92B9F21EC6B90100BA7EF4 /* TableViewCell.swift */; }; 16 | 9A92B9F51EC6B90100BA7EF4 /* TableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A92B9F31EC6B90100BA7EF4 /* TableViewCell.xib */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 9A1F95D61EC5B741008617DE /* TableViewHeaderAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TableViewHeaderAnimation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 9A1F95D91EC5B741008617DE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 22 | 9A1F95E01EC5B741008617DE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 23 | 9A1F95E31EC5B741008617DE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 24 | 9A1F95E51EC5B741008617DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | 9A92B9EC1EC6987300BA7EF4 /* AnimationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationViewController.swift; sourceTree = ""; }; 26 | 9A92B9F01EC6AAB100BA7EF4 /* HeaderAnimationTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderAnimationTableView.swift; sourceTree = ""; }; 27 | 9A92B9F21EC6B90100BA7EF4 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; }; 28 | 9A92B9F31EC6B90100BA7EF4 /* TableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TableViewCell.xib; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 9A1F95D31EC5B741008617DE /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 9A1F95CD1EC5B741008617DE = { 43 | isa = PBXGroup; 44 | children = ( 45 | 9A1F95D81EC5B741008617DE /* TableViewHeaderAnimation */, 46 | 9A1F95D71EC5B741008617DE /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | 9A1F95D71EC5B741008617DE /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 9A1F95D61EC5B741008617DE /* TableViewHeaderAnimation.app */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | 9A1F95D81EC5B741008617DE /* TableViewHeaderAnimation */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 9A1F95D91EC5B741008617DE /* AppDelegate.swift */, 62 | 9A92B9EC1EC6987300BA7EF4 /* AnimationViewController.swift */, 63 | 9A92B9F01EC6AAB100BA7EF4 /* HeaderAnimationTableView.swift */, 64 | 9A92B9F21EC6B90100BA7EF4 /* TableViewCell.swift */, 65 | 9A92B9F31EC6B90100BA7EF4 /* TableViewCell.xib */, 66 | 9A1F95E01EC5B741008617DE /* Assets.xcassets */, 67 | 9A1F95E21EC5B741008617DE /* LaunchScreen.storyboard */, 68 | 9A1F95E51EC5B741008617DE /* Info.plist */, 69 | ); 70 | path = TableViewHeaderAnimation; 71 | sourceTree = ""; 72 | }; 73 | /* End PBXGroup section */ 74 | 75 | /* Begin PBXNativeTarget section */ 76 | 9A1F95D51EC5B741008617DE /* TableViewHeaderAnimation */ = { 77 | isa = PBXNativeTarget; 78 | buildConfigurationList = 9A1F95E81EC5B741008617DE /* Build configuration list for PBXNativeTarget "TableViewHeaderAnimation" */; 79 | buildPhases = ( 80 | 9A1F95D21EC5B741008617DE /* Sources */, 81 | 9A1F95D31EC5B741008617DE /* Frameworks */, 82 | 9A1F95D41EC5B741008617DE /* Resources */, 83 | ); 84 | buildRules = ( 85 | ); 86 | dependencies = ( 87 | ); 88 | name = TableViewHeaderAnimation; 89 | productName = TableViewHeaderAnimation; 90 | productReference = 9A1F95D61EC5B741008617DE /* TableViewHeaderAnimation.app */; 91 | productType = "com.apple.product-type.application"; 92 | }; 93 | /* End PBXNativeTarget section */ 94 | 95 | /* Begin PBXProject section */ 96 | 9A1F95CE1EC5B741008617DE /* Project object */ = { 97 | isa = PBXProject; 98 | attributes = { 99 | LastSwiftUpdateCheck = 0820; 100 | LastUpgradeCheck = 0940; 101 | ORGANIZATIONNAME = as_one; 102 | TargetAttributes = { 103 | 9A1F95D51EC5B741008617DE = { 104 | CreatedOnToolsVersion = 8.2.1; 105 | DevelopmentTeam = N29NG87DU4; 106 | LastSwiftMigration = 0940; 107 | ProvisioningStyle = Automatic; 108 | }; 109 | }; 110 | }; 111 | buildConfigurationList = 9A1F95D11EC5B741008617DE /* Build configuration list for PBXProject "TableViewHeaderAnimation" */; 112 | compatibilityVersion = "Xcode 3.2"; 113 | developmentRegion = English; 114 | hasScannedForEncodings = 0; 115 | knownRegions = ( 116 | en, 117 | Base, 118 | ); 119 | mainGroup = 9A1F95CD1EC5B741008617DE; 120 | productRefGroup = 9A1F95D71EC5B741008617DE /* Products */; 121 | projectDirPath = ""; 122 | projectRoot = ""; 123 | targets = ( 124 | 9A1F95D51EC5B741008617DE /* TableViewHeaderAnimation */, 125 | ); 126 | }; 127 | /* End PBXProject section */ 128 | 129 | /* Begin PBXResourcesBuildPhase section */ 130 | 9A1F95D41EC5B741008617DE /* Resources */ = { 131 | isa = PBXResourcesBuildPhase; 132 | buildActionMask = 2147483647; 133 | files = ( 134 | 9A1F95E41EC5B741008617DE /* LaunchScreen.storyboard in Resources */, 135 | 9A92B9F51EC6B90100BA7EF4 /* TableViewCell.xib in Resources */, 136 | 9A1F95E11EC5B741008617DE /* Assets.xcassets in Resources */, 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | /* End PBXResourcesBuildPhase section */ 141 | 142 | /* Begin PBXSourcesBuildPhase section */ 143 | 9A1F95D21EC5B741008617DE /* Sources */ = { 144 | isa = PBXSourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 9A92B9F11EC6AAB100BA7EF4 /* HeaderAnimationTableView.swift in Sources */, 148 | 9A92B9F41EC6B90100BA7EF4 /* TableViewCell.swift in Sources */, 149 | 9A92B9ED1EC6987300BA7EF4 /* AnimationViewController.swift in Sources */, 150 | 9A1F95DA1EC5B741008617DE /* AppDelegate.swift in Sources */, 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | /* End PBXSourcesBuildPhase section */ 155 | 156 | /* Begin PBXVariantGroup section */ 157 | 9A1F95E21EC5B741008617DE /* LaunchScreen.storyboard */ = { 158 | isa = PBXVariantGroup; 159 | children = ( 160 | 9A1F95E31EC5B741008617DE /* Base */, 161 | ); 162 | name = LaunchScreen.storyboard; 163 | sourceTree = ""; 164 | }; 165 | /* End PBXVariantGroup section */ 166 | 167 | /* Begin XCBuildConfiguration section */ 168 | 9A1F95E61EC5B741008617DE /* Debug */ = { 169 | isa = XCBuildConfiguration; 170 | buildSettings = { 171 | ALWAYS_SEARCH_USER_PATHS = NO; 172 | CLANG_ANALYZER_NONNULL = YES; 173 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 174 | CLANG_CXX_LIBRARY = "libc++"; 175 | CLANG_ENABLE_MODULES = YES; 176 | CLANG_ENABLE_OBJC_ARC = YES; 177 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 178 | CLANG_WARN_BOOL_CONVERSION = YES; 179 | CLANG_WARN_COMMA = YES; 180 | CLANG_WARN_CONSTANT_CONVERSION = YES; 181 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 182 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 183 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 184 | CLANG_WARN_EMPTY_BODY = YES; 185 | CLANG_WARN_ENUM_CONVERSION = YES; 186 | CLANG_WARN_INFINITE_RECURSION = YES; 187 | CLANG_WARN_INT_CONVERSION = YES; 188 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 189 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 190 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 191 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 192 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 193 | CLANG_WARN_STRICT_PROTOTYPES = YES; 194 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 195 | CLANG_WARN_UNREACHABLE_CODE = YES; 196 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 197 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 198 | COPY_PHASE_STRIP = NO; 199 | DEBUG_INFORMATION_FORMAT = dwarf; 200 | ENABLE_STRICT_OBJC_MSGSEND = YES; 201 | ENABLE_TESTABILITY = YES; 202 | GCC_C_LANGUAGE_STANDARD = gnu99; 203 | GCC_DYNAMIC_NO_PIC = NO; 204 | GCC_NO_COMMON_BLOCKS = YES; 205 | GCC_OPTIMIZATION_LEVEL = 0; 206 | GCC_PREPROCESSOR_DEFINITIONS = ( 207 | "DEBUG=1", 208 | "$(inherited)", 209 | ); 210 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 211 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 212 | GCC_WARN_UNDECLARED_SELECTOR = YES; 213 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 214 | GCC_WARN_UNUSED_FUNCTION = YES; 215 | GCC_WARN_UNUSED_VARIABLE = YES; 216 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 217 | MTL_ENABLE_DEBUG_INFO = YES; 218 | ONLY_ACTIVE_ARCH = YES; 219 | SDKROOT = iphoneos; 220 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 221 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 222 | TARGETED_DEVICE_FAMILY = "1,2"; 223 | }; 224 | name = Debug; 225 | }; 226 | 9A1F95E71EC5B741008617DE /* Release */ = { 227 | isa = XCBuildConfiguration; 228 | buildSettings = { 229 | ALWAYS_SEARCH_USER_PATHS = NO; 230 | CLANG_ANALYZER_NONNULL = YES; 231 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 232 | CLANG_CXX_LIBRARY = "libc++"; 233 | CLANG_ENABLE_MODULES = YES; 234 | CLANG_ENABLE_OBJC_ARC = YES; 235 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 236 | CLANG_WARN_BOOL_CONVERSION = YES; 237 | CLANG_WARN_COMMA = YES; 238 | CLANG_WARN_CONSTANT_CONVERSION = YES; 239 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 240 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 241 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 242 | CLANG_WARN_EMPTY_BODY = YES; 243 | CLANG_WARN_ENUM_CONVERSION = YES; 244 | CLANG_WARN_INFINITE_RECURSION = YES; 245 | CLANG_WARN_INT_CONVERSION = YES; 246 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 247 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 248 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 249 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 250 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 251 | CLANG_WARN_STRICT_PROTOTYPES = YES; 252 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 253 | CLANG_WARN_UNREACHABLE_CODE = YES; 254 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 255 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 256 | COPY_PHASE_STRIP = NO; 257 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 258 | ENABLE_NS_ASSERTIONS = NO; 259 | ENABLE_STRICT_OBJC_MSGSEND = YES; 260 | GCC_C_LANGUAGE_STANDARD = gnu99; 261 | GCC_NO_COMMON_BLOCKS = YES; 262 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 263 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 264 | GCC_WARN_UNDECLARED_SELECTOR = YES; 265 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 266 | GCC_WARN_UNUSED_FUNCTION = YES; 267 | GCC_WARN_UNUSED_VARIABLE = YES; 268 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 269 | MTL_ENABLE_DEBUG_INFO = NO; 270 | SDKROOT = iphoneos; 271 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 272 | TARGETED_DEVICE_FAMILY = "1,2"; 273 | VALIDATE_PRODUCT = YES; 274 | }; 275 | name = Release; 276 | }; 277 | 9A1F95E91EC5B741008617DE /* Debug */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 281 | DEVELOPMENT_TEAM = N29NG87DU4; 282 | INFOPLIST_FILE = TableViewHeaderAnimation/Info.plist; 283 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 284 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 285 | PRODUCT_BUNDLE_IDENTIFIER = xuelin.TableViewHeaderAnimation; 286 | PRODUCT_NAME = "$(TARGET_NAME)"; 287 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 288 | SWIFT_VERSION = 4.0; 289 | TARGETED_DEVICE_FAMILY = 1; 290 | }; 291 | name = Debug; 292 | }; 293 | 9A1F95EA1EC5B741008617DE /* Release */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 297 | DEVELOPMENT_TEAM = N29NG87DU4; 298 | INFOPLIST_FILE = TableViewHeaderAnimation/Info.plist; 299 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 301 | PRODUCT_BUNDLE_IDENTIFIER = xuelin.TableViewHeaderAnimation; 302 | PRODUCT_NAME = "$(TARGET_NAME)"; 303 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 304 | SWIFT_VERSION = 4.0; 305 | TARGETED_DEVICE_FAMILY = 1; 306 | }; 307 | name = Release; 308 | }; 309 | /* End XCBuildConfiguration section */ 310 | 311 | /* Begin XCConfigurationList section */ 312 | 9A1F95D11EC5B741008617DE /* Build configuration list for PBXProject "TableViewHeaderAnimation" */ = { 313 | isa = XCConfigurationList; 314 | buildConfigurations = ( 315 | 9A1F95E61EC5B741008617DE /* Debug */, 316 | 9A1F95E71EC5B741008617DE /* Release */, 317 | ); 318 | defaultConfigurationIsVisible = 0; 319 | defaultConfigurationName = Release; 320 | }; 321 | 9A1F95E81EC5B741008617DE /* Build configuration list for PBXNativeTarget "TableViewHeaderAnimation" */ = { 322 | isa = XCConfigurationList; 323 | buildConfigurations = ( 324 | 9A1F95E91EC5B741008617DE /* Debug */, 325 | 9A1F95EA1EC5B741008617DE /* Release */, 326 | ); 327 | defaultConfigurationIsVisible = 0; 328 | defaultConfigurationName = Release; 329 | }; 330 | /* End XCConfigurationList section */ 331 | }; 332 | rootObject = 9A1F95CE1EC5B741008617DE /* Project object */; 333 | } 334 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/project.xcworkspace/xcuserdata/as_one.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation.xcodeproj/project.xcworkspace/xcuserdata/as_one.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/project.xcworkspace/xcuserdata/xuelin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation.xcodeproj/project.xcworkspace/xcuserdata/xuelin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/xcuserdata/as_one.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/xcuserdata/as_one.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TableViewHeaderAnimation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | TableViewHeaderAnimation.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/xcuserdata/xuelin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/xcuserdata/xuelin.xcuserdatad/xcschemes/TableViewHeaderAnimation.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation.xcodeproj/xcuserdata/xuelin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TableViewHeaderAnimation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9A1F95D51EC5B741008617DE 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/AnimationViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationViewController.swift 3 | // TableViewHeaderAnimation 4 | // 5 | // Created by xuelin on 2017/5/13. 6 | // Copyright © 2017年 as_one. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let cellIdentify = "cellIdentify" 12 | let SCREEN_WIDTH = UIScreen.main.bounds.width; 13 | let SCREEN_HEIGHT = UIScreen.main.bounds.height; 14 | 15 | class AnimationViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 16 | 17 | private var mainTableView:HeaderAnimationTableView! 18 | 19 | private var selectBtn:UIButton! 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | 24 | // Do any additional setup after loading the view. 25 | self.view.backgroundColor = UIColor.white; 26 | self.title = "FollowAndFold" 27 | let topHeight = (self.navigationController?.navigationBar.frame.size.height)! + UIApplication.shared.statusBarFrame.size.height 28 | mainTableView = HeaderAnimationTableView.init(frame: CGRect.init(x: 0, y: topHeight, width: SCREEN_WIDTH, height: SCREEN_HEIGHT - topHeight), style: .plain) 29 | self.view.addSubview(mainTableView) 30 | mainTableView.settingInfo.followAnimationType = .FollowAndFold; 31 | if #available(iOS 11.0, *) { 32 | mainTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.never 33 | } else { 34 | self.automaticallyAdjustsScrollViewInsets = false; 35 | } 36 | mainTableView.settingInfo.headerViewActualHeight = 200; 37 | mainTableView.tableFooterView = UIView.init() 38 | mainTableView.estimatedRowHeight = 100 39 | mainTableView.rowHeight = UITableViewAutomaticDimension 40 | let imageView = UIImageView.init(image: UIImage.init(named: "b")) 41 | imageView.frame = CGRect.init(x: 0, y: 0, width: SCREEN_WIDTH, height: 200) 42 | mainTableView.topView = imageView 43 | mainTableView.delegate = self 44 | mainTableView.dataSource = self 45 | mainTableView.register(UINib.init(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: cellIdentify) 46 | self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "Action", style: UIBarButtonItemStyle.plain, target: self, action: #selector(action)) 47 | } 48 | 49 | @objc func action() { 50 | let alertVc = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet) 51 | // 下拉跟随 52 | let followAction = UIAlertAction.init(title: "Follow", style: .default) { (UIAlertAction) in 53 | self.followAction(); 54 | } 55 | alertVc.addAction(followAction) 56 | // 下拉跟随并缩放Header 57 | let followAndStretchAction = UIAlertAction.init(title: "FollowAndStretch", style: .default) { (UIAlertAction) in 58 | self.followAndStretchAction(); 59 | } 60 | alertVc.addAction(followAndStretchAction) 61 | // Header固定 62 | let holdAction = UIAlertAction.init(title: "Hold", style: .default) { (UIAlertAction) in 63 | self.holdAction(); 64 | } 65 | alertVc.addAction(holdAction) 66 | // 上拉固定下拉放大 67 | let holdAndStretchAction = UIAlertAction.init(title: "HoldAndStretchAction", style: .default) { (UIAlertAction) in 68 | self.holdAndStretchAction(); 69 | } 70 | alertVc.addAction(holdAndStretchAction) 71 | 72 | // 同时滚动但有折叠效果 73 | let holdAndFoldAction = UIAlertAction.init(title: "FollowAndFold", style: .default) { (UIAlertAction) in 74 | self.followAndFoldAction(); 75 | } 76 | alertVc.addAction(holdAndFoldAction) 77 | 78 | let cancelAction = UIAlertAction.init(title: "Celcel", style: .cancel) { (UIAlertAction) in 79 | NSLog("Cancel", "") 80 | } 81 | alertVc.addAction(cancelAction) 82 | self.present(alertVc, animated: true, completion: nil) 83 | } 84 | 85 | // MARK: - 86 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 87 | return 30; 88 | } 89 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 90 | let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentify, for: indexPath) 91 | return cell 92 | } 93 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 94 | tableView.deselectRow(at: indexPath, animated: true) 95 | } 96 | 97 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 98 | mainTableView.scrollViewDidScroll(mainTableView) 99 | } 100 | 101 | func followAction (){ 102 | mainTableView.settingInfo.followAnimationType = .Follow 103 | self.title = "Follow" 104 | } 105 | 106 | func followAndStretchAction (){ 107 | mainTableView.settingInfo.stretchType = .StretchEqual 108 | mainTableView.settingInfo.followAnimationType = .FollowAndStretch 109 | self.title = "FollowAndStretch" 110 | } 111 | 112 | func holdAction() { 113 | mainTableView.settingInfo.followAnimationType = .Hold 114 | self.title = "Hold" 115 | } 116 | 117 | func holdAndStretchAction() { 118 | mainTableView.settingInfo.stretchType = .StretchSameRate 119 | mainTableView.settingInfo.followAnimationType = .HoldAndStretch 120 | self.title = "HoldAndStretch" 121 | } 122 | func followAndFoldAction() { 123 | mainTableView.settingInfo.stretchType = .StretchSameRate 124 | mainTableView.settingInfo.followAnimationType = .FollowAndFold 125 | self.title = "FollowAndFold" 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TableViewHeaderAnimation 4 | // 5 | // Created by xuelin on 2017/5/12. 6 | // Copyright © 2017年 as_one. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 20 | self.window = UIWindow.init(frame: UIScreen.main.bounds) 21 | self.window?.rootViewController = UINavigationController.init(rootViewController: AnimationViewController()); 22 | self.window?.backgroundColor = UIColor.white 23 | self.window?.makeKeyAndVisible() 24 | 25 | return true 26 | } 27 | 28 | func applicationWillResignActive(_ application: UIApplication) { 29 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 30 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 31 | } 32 | 33 | func applicationDidEnterBackground(_ application: UIApplication) { 34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | func applicationWillEnterForeground(_ application: UIApplication) { 39 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 40 | } 41 | 42 | func applicationDidBecomeActive(_ application: UIApplication) { 43 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 44 | } 45 | 46 | func applicationWillTerminate(_ application: UIApplication) { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-40.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-60.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-58.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-87.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-80.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-120.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-121.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-180.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "idiom" : "ipad", 53 | "size" : "20x20", 54 | "scale" : "1x" 55 | }, 56 | { 57 | "idiom" : "ipad", 58 | "size" : "20x20", 59 | "scale" : "2x" 60 | }, 61 | { 62 | "idiom" : "ipad", 63 | "size" : "29x29", 64 | "scale" : "1x" 65 | }, 66 | { 67 | "idiom" : "ipad", 68 | "size" : "29x29", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "idiom" : "ipad", 73 | "size" : "40x40", 74 | "scale" : "1x" 75 | }, 76 | { 77 | "idiom" : "ipad", 78 | "size" : "40x40", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "idiom" : "ipad", 83 | "size" : "76x76", 84 | "scale" : "1x" 85 | }, 86 | { 87 | "idiom" : "ipad", 88 | "size" : "76x76", 89 | "scale" : "2x" 90 | }, 91 | { 92 | "idiom" : "ipad", 93 | "size" : "83.5x83.5", 94 | "scale" : "2x" 95 | }, 96 | { 97 | "size" : "1024x1024", 98 | "idiom" : "ios-marketing", 99 | "filename" : "Icon-1024.png", 100 | "scale" : "1x" 101 | } 102 | ], 103 | "info" : { 104 | "version" : 1, 105 | "author" : "xcode" 106 | } 107 | } -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-120.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-121.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-121.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-180.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-58.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-60.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-80.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/AppIcon.appiconset/Icon-87.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/b.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "b.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/b.imageset/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/b.imageset/b.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/phil.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "phil.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Assets.xcassets/phil.imageset/phil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/Assets.xcassets/phil.imageset/phil.png -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/HeaderAnimationTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderAnimationTableView.swift 3 | // TableViewHeaderAnimation 4 | // 5 | // Created by xuelin on 2017/5/13. 6 | // Copyright © 2017年 as_one. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | // 到达顶部和底部的闭包 11 | typealias TableViewReachTopViewBottomClosure = (_ isTopDirection: Bool) -> Void; 12 | 13 | class HeaderAnimationTableView: UITableView,UITableViewDelegate { 14 | 15 | /// 保存上次的contentOffSetY值 , 用于判断滚动方向 16 | private var previousContentOffSetY:CGFloat! 17 | private var topViewHeight:CGFloat! 18 | private var originWidth:CGFloat! = 0 19 | private var originHeight:CGFloat! = 0 20 | 21 | /// 滚动到topView的最下部分时调用 22 | var reachbottomClosure:TableViewReachTopViewBottomClosure! 23 | 24 | /// 先设置settingInfo后再设置topView 25 | var settingInfo:SwipAnimationViewInfo = SwipAnimationViewInfo() 26 | 27 | var coverView : UIView? 28 | 29 | var topView:UIView? { 30 | didSet { 31 | 32 | let view = UIView.init(frame: CGRect.init(x:0, y:0, width:self.frame.width, height:settingInfo.headerViewActualHeight)) 33 | view.alpha = 0; 34 | self.tableHeaderView = view 35 | originWidth = topView?.frame.width 36 | topView?.frame = CGRect.init(x:0, y:0, width:originWidth, height:settingInfo.headerViewActualHeight) 37 | originHeight = topView?.frame.height 38 | settingInfo.headerViewActualHeight = settingInfo.headerViewActualHeight 39 | self.insertSubview(topView!, at: 0) 40 | 41 | let coverView = UIView() 42 | coverView.backgroundColor = UIColor.black 43 | coverView.alpha = 0 44 | coverView.frame = (topView?.frame)! 45 | self.coverView = coverView 46 | topView?.addSubview(self.coverView!) 47 | } 48 | } 49 | 50 | /** 51 | * 页面设置信息 52 | */ 53 | struct SwipAnimationViewInfo { 54 | /// 上方headerView的露出的实际显示高度 55 | var headerViewActualHeight : CGFloat = 200 56 | 57 | /// 上方headerView随滚动旋转的最大角度 (0 ~ 90度)(对应值为0 ~ 1) 58 | var headerViewRotateMaxRadious:Double = Double.pi / 2; 59 | 60 | 61 | /// 上部页面跟随下部页面的动画方式 62 | var followAnimationType:TopViewAnimationType = .Follow 63 | 64 | var stretchType:StretchType = .StretchSameRate 65 | } 66 | 67 | /** 68 | * 页面滑动时 , 上部画面的动画 69 | */ 70 | enum TopViewAnimationType { 71 | /** 72 | * 页面滑动时 , 上部画面保持原位 73 | */ 74 | case Hold 75 | /** 76 | * 页面滑动时 , 上部画面保持原位 , 并且到最顶部时有拉伸动画 77 | */ 78 | case HoldAndStretch 79 | /** 80 | * 页面滑动时 , 上部画面的位移与下部页面一致 , 即页面同步 81 | */ 82 | case Follow 83 | /** 84 | 页面滑动时 , 上部画面的位移与下部页面一致 , 即页面同步 , 并到底后有拉伸 85 | */ 86 | case FollowAndStretch 87 | /** 88 | 页面滑动时,上部位移是底部的一半,呈现的折叠效果 89 | */ 90 | case FollowAndFold 91 | } 92 | 93 | enum StretchType { 94 | /// 同比例缩放 95 | case StretchSameRate 96 | /// 方形缩放 97 | case StretchEqual 98 | } 99 | 100 | required init?(coder aDecoder: NSCoder) { 101 | super.init(coder: aDecoder) 102 | fatalError() 103 | } 104 | 105 | override init(frame: CGRect, style: UITableViewStyle) { 106 | super.init(frame: frame, style: .plain) 107 | self.delegate = self 108 | self.clipsToBounds = false 109 | } 110 | 111 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 112 | 113 | self.topView?.removeFromSuperview(); 114 | if settingInfo.followAnimationType == .FollowAndFold { 115 | self.backgroundView = UIView.init(); 116 | self.backgroundView?.insertSubview(topView!, at: 0) 117 | // 遮罩alpha改变 118 | self.coverView?.alpha = scrollView.contentOffset.y / (self.settingInfo.headerViewActualHeight * 2) 119 | } else { 120 | self.insertSubview(topView!, at: 0) 121 | self.coverView?.alpha = 0; 122 | } 123 | 124 | switch settingInfo.followAnimationType { 125 | case .Follow : self.headerAnimationFollow(contentOffSetY: scrollView.contentOffset.y) 126 | case .Hold : self.headerAnimationHold(contentOffSetY: scrollView.contentOffset.y) 127 | case .HoldAndStretch : self.headerAnimationHoldAndStretch(contentOffSetY: scrollView.contentOffset.y) 128 | case .FollowAndStretch : self.headerAnimationFollowAndStretch(contentOffSetY: scrollView.contentOffset.y) 129 | case .FollowAndFold : self.headerAnimationFold(contentOffSetY: scrollView.contentOffset.y) 130 | } 131 | // 判断是否滚动到上方view的最下部 132 | if abs(scrollView.contentOffset.y - settingInfo.headerViewActualHeight) < 20 { 133 | if reachbottomClosure != nil { 134 | reachbottomClosure!(scrollView.contentOffset.y > previousContentOffSetY) 135 | } 136 | } 137 | previousContentOffSetY = scrollView.contentOffset.y 138 | } 139 | 140 | // 不同的animationType作不同的动画处理 141 | func headerAnimationFollow(contentOffSetY:CGFloat) { 142 | if contentOffSetY <= 0 { 143 | topView?.frame = CGRect.init(x:0, y: contentOffSetY / 2.0, width:self.originWidth, height:self.originHeight) 144 | 145 | } 146 | } 147 | 148 | func headerAnimationFollowAndStretch(contentOffSetY:CGFloat) { 149 | self.headerAnimationFollow(contentOffSetY: contentOffSetY) 150 | if contentOffSetY <= 0 { 151 | let actualOffSetY = -contentOffSetY 152 | var actualOffSetX:CGFloat = 0 153 | if settingInfo.stretchType == .StretchEqual { 154 | actualOffSetX = 0 155 | } else { 156 | actualOffSetX = actualOffSetY * originWidth / originHeight 157 | } 158 | self.topView?.frame = CGRect.init(x:-actualOffSetX / 2.0, y:contentOffSetY, width:self.originWidth + actualOffSetX, height:self.originHeight + actualOffSetY) 159 | } 160 | } 161 | 162 | func headerAnimationHold(contentOffSetY:CGFloat) { 163 | if contentOffSetY > 0 { 164 | topView?.frame = CGRect.init(x:0, y:contentOffSetY, width:topView!.frame.width, height:(topView?.frame.height)!) 165 | } else if contentOffSetY <= 0 { 166 | topView?.frame = CGRect.init(x:0, y:0, width:self.originWidth, height:self.originHeight) 167 | } 168 | } 169 | 170 | func headerAnimationFold(contentOffSetY:CGFloat) { 171 | 172 | if contentOffSetY > 0 && contentOffSetY < self.settingInfo.headerViewActualHeight { 173 | topView?.frame = CGRect.init(x:0, y:-contentOffSetY * 0.5, width:topView!.frame.width, height:(topView?.frame.height)!) 174 | } else if contentOffSetY <= 0 { 175 | topView?.frame = CGRect.init(x:0, y:-contentOffSetY, width:self.originWidth, height:self.originHeight) 176 | } 177 | } 178 | 179 | func headerAnimationHoldAndStretch(contentOffSetY:CGFloat) { 180 | self.headerAnimationHold(contentOffSetY: contentOffSetY) 181 | if contentOffSetY <= 0 { 182 | let actualOffSetY = -contentOffSetY 183 | var actualOffSetX:CGFloat = 0 184 | if settingInfo.stretchType == .StretchEqual { 185 | actualOffSetX = 0 186 | } else { 187 | actualOffSetX = actualOffSetY * originWidth / originHeight 188 | } 189 | self.topView?.frame = CGRect.init(x:-actualOffSetX / 2.0, y:contentOffSetY, width:self.originWidth + actualOffSetX, height:self.originHeight + actualOffSetY) 190 | } 191 | 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UIStatusBarHidden 30 | 31 | UIStatusBarStyle 32 | UIStatusBarStyleDefault 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/TableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.swift 3 | // TableViewHeaderAnimation 4 | // 5 | // Created by xuelin on 2017/5/13. 6 | // Copyright © 2017年 as_one. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableViewCell: UITableViewCell { 12 | @IBOutlet weak var ImgView: UIImageView! 13 | 14 | override func awakeFromNib() { 15 | super.awakeFromNib() 16 | self.ImgView.image = UIImage.init(named: "b"); 17 | } 18 | 19 | override func setSelected(_ selected: Bool, animated: Bool) { 20 | super.setSelected(selected, animated: animated) 21 | 22 | // Configure the view for the selected state 23 | } 24 | 25 | override func prepareForReuse() { 26 | self.ImgView.image = UIImage.init(named: "phil"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/TableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /TableViewHeaderAnimation/WeChat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xlsd/SDTableViewHeaderAnimation/cf591492ac07b5d3ff69f0da3eb568990bc8f1d7/TableViewHeaderAnimation/WeChat.gif --------------------------------------------------------------------------------