├── .gitignore ├── AVPlayer.xcodeproj └── project.pbxproj ├── AVPlayer ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── back_leftButton.imageset │ │ ├── Contents.json │ │ ├── back_leftButton@2x.png │ │ └── back_leftButton@3x.png │ ├── icon_gzt1.imageset │ │ ├── Contents.json │ │ └── icon_gzt1.png │ ├── icon_gzt2.imageset │ │ ├── Contents.json │ │ └── icon_gzt2.png │ ├── icon_wd1.imageset │ │ ├── Contents.json │ │ └── icon_wd1.png │ └── icon_wd2.imageset │ │ ├── Contents.json │ │ └── icon_wd2.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── HomeTableViewCell.swift ├── Info.plist ├── SelectScrollview.swift ├── TJFBaseNavigationViewController.swift ├── TJFBaseViewController.swift ├── TJFHomeViewController.swift ├── TJFMainTabBarViewController.swift ├── TJFMyViewController.swift ├── TestViewViewController.swift └── ViewController.swift ├── AVPlayerTests ├── AVPlayerTests.swift └── Info.plist ├── AVPlayerUITests ├── AVPlayerUITests.swift └── Info.plist ├── Podfile ├── Podfile.lock ├── README.md └── avplayerGift.gif /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata 2 | /Pods 3 | *.xcworkspace 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /AVPlayer.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A52108F344A51890DFA93F36 /* Pods_AVPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 335068B28DDFAB6C76AFF8D7 /* Pods_AVPlayer.framework */; }; 11 | AD0179831F7CD144005365D6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD0179821F7CD144005365D6 /* AppDelegate.swift */; }; 12 | AD0179851F7CD144005365D6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD0179841F7CD144005365D6 /* ViewController.swift */; }; 13 | AD0179881F7CD144005365D6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AD0179861F7CD144005365D6 /* Main.storyboard */; }; 14 | AD01798A1F7CD144005365D6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AD0179891F7CD144005365D6 /* Assets.xcassets */; }; 15 | AD01798D1F7CD144005365D6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AD01798B1F7CD144005365D6 /* LaunchScreen.storyboard */; }; 16 | AD0179981F7CD144005365D6 /* AVPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD0179971F7CD144005365D6 /* AVPlayerTests.swift */; }; 17 | AD0179A31F7CD144005365D6 /* AVPlayerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD0179A21F7CD144005365D6 /* AVPlayerUITests.swift */; }; 18 | AD7A3CED1F99DC9600F4EA55 /* TestViewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD7A3CEC1F99DC9600F4EA55 /* TestViewViewController.swift */; }; 19 | ADC82E3F1F8C649200B22ACE /* SelectScrollview.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADC82E3E1F8C649200B22ACE /* SelectScrollview.swift */; }; 20 | ADCDC9401F7DDD1D00996FD1 /* TJFBaseNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCDC93F1F7DDD1D00996FD1 /* TJFBaseNavigationViewController.swift */; }; 21 | ADCDC9421F7DE51600996FD1 /* TJFMainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCDC9411F7DE51600996FD1 /* TJFMainTabBarViewController.swift */; }; 22 | ADCDC9441F7DE55500996FD1 /* TJFBaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCDC9431F7DE55500996FD1 /* TJFBaseViewController.swift */; }; 23 | ADCDC9461F7DE57E00996FD1 /* TJFHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCDC9451F7DE57E00996FD1 /* TJFHomeViewController.swift */; }; 24 | ADCDC9481F7DE59000996FD1 /* TJFMyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCDC9471F7DE59000996FD1 /* TJFMyViewController.swift */; }; 25 | ADCDC94A1F7DFAC500996FD1 /* HomeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCDC9491F7DFAC500996FD1 /* HomeTableViewCell.swift */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | AD0179941F7CD144005365D6 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = AD0179771F7CD144005365D6 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = AD01797E1F7CD144005365D6; 34 | remoteInfo = AVPlayer; 35 | }; 36 | AD01799F1F7CD144005365D6 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = AD0179771F7CD144005365D6 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = AD01797E1F7CD144005365D6; 41 | remoteInfo = AVPlayer; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 335068B28DDFAB6C76AFF8D7 /* Pods_AVPlayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AVPlayer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 658A303F8BBF9667910CADD2 /* Pods-AVPlayer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AVPlayer.release.xcconfig"; path = "Pods/Target Support Files/Pods-AVPlayer/Pods-AVPlayer.release.xcconfig"; sourceTree = ""; }; 48 | 8374F277B246C84259B2D615 /* Pods-AVPlayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AVPlayer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AVPlayer/Pods-AVPlayer.debug.xcconfig"; sourceTree = ""; }; 49 | AD01797F1F7CD144005365D6 /* AVPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AVPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | AD0179821F7CD144005365D6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 51 | AD0179841F7CD144005365D6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 52 | AD0179871F7CD144005365D6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 53 | AD0179891F7CD144005365D6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54 | AD01798C1F7CD144005365D6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 55 | AD01798E1F7CD144005365D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | AD0179931F7CD144005365D6 /* AVPlayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AVPlayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | AD0179971F7CD144005365D6 /* AVPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerTests.swift; sourceTree = ""; }; 58 | AD0179991F7CD144005365D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | AD01799E1F7CD144005365D6 /* AVPlayerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AVPlayerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | AD0179A21F7CD144005365D6 /* AVPlayerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerUITests.swift; sourceTree = ""; }; 61 | AD0179A41F7CD144005365D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | AD7A3CEC1F99DC9600F4EA55 /* TestViewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestViewViewController.swift; sourceTree = ""; }; 63 | ADC82E3E1F8C649200B22ACE /* SelectScrollview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectScrollview.swift; sourceTree = ""; }; 64 | ADCDC93F1F7DDD1D00996FD1 /* TJFBaseNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TJFBaseNavigationViewController.swift; sourceTree = ""; }; 65 | ADCDC9411F7DE51600996FD1 /* TJFMainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TJFMainTabBarViewController.swift; sourceTree = ""; }; 66 | ADCDC9431F7DE55500996FD1 /* TJFBaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TJFBaseViewController.swift; sourceTree = ""; }; 67 | ADCDC9451F7DE57E00996FD1 /* TJFHomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TJFHomeViewController.swift; sourceTree = ""; }; 68 | ADCDC9471F7DE59000996FD1 /* TJFMyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TJFMyViewController.swift; sourceTree = ""; }; 69 | ADCDC9491F7DFAC500996FD1 /* HomeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTableViewCell.swift; sourceTree = ""; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | AD01797C1F7CD144005365D6 /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | A52108F344A51890DFA93F36 /* Pods_AVPlayer.framework in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | AD0179901F7CD144005365D6 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | AD01799B1F7CD144005365D6 /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 04CC467743DB2FE08A286E19 /* Pods */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 8374F277B246C84259B2D615 /* Pods-AVPlayer.debug.xcconfig */, 102 | 658A303F8BBF9667910CADD2 /* Pods-AVPlayer.release.xcconfig */, 103 | ); 104 | name = Pods; 105 | sourceTree = ""; 106 | }; 107 | 5405849CD3F7BD59A3837B1E /* Frameworks */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 335068B28DDFAB6C76AFF8D7 /* Pods_AVPlayer.framework */, 111 | ); 112 | name = Frameworks; 113 | sourceTree = ""; 114 | }; 115 | AD0179761F7CD144005365D6 = { 116 | isa = PBXGroup; 117 | children = ( 118 | AD0179811F7CD144005365D6 /* AVPlayer */, 119 | AD0179961F7CD144005365D6 /* AVPlayerTests */, 120 | AD0179A11F7CD144005365D6 /* AVPlayerUITests */, 121 | AD0179801F7CD144005365D6 /* Products */, 122 | 04CC467743DB2FE08A286E19 /* Pods */, 123 | 5405849CD3F7BD59A3837B1E /* Frameworks */, 124 | ); 125 | sourceTree = ""; 126 | }; 127 | AD0179801F7CD144005365D6 /* Products */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | AD01797F1F7CD144005365D6 /* AVPlayer.app */, 131 | AD0179931F7CD144005365D6 /* AVPlayerTests.xctest */, 132 | AD01799E1F7CD144005365D6 /* AVPlayerUITests.xctest */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | AD0179811F7CD144005365D6 /* AVPlayer */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | AD0179821F7CD144005365D6 /* AppDelegate.swift */, 141 | AD0179841F7CD144005365D6 /* ViewController.swift */, 142 | ADCDC93F1F7DDD1D00996FD1 /* TJFBaseNavigationViewController.swift */, 143 | ADCDC9411F7DE51600996FD1 /* TJFMainTabBarViewController.swift */, 144 | ADCDC9431F7DE55500996FD1 /* TJFBaseViewController.swift */, 145 | ADCDC9451F7DE57E00996FD1 /* TJFHomeViewController.swift */, 146 | ADCDC9471F7DE59000996FD1 /* TJFMyViewController.swift */, 147 | ADCDC9491F7DFAC500996FD1 /* HomeTableViewCell.swift */, 148 | ADC82E3E1F8C649200B22ACE /* SelectScrollview.swift */, 149 | AD7A3CEC1F99DC9600F4EA55 /* TestViewViewController.swift */, 150 | AD0179861F7CD144005365D6 /* Main.storyboard */, 151 | AD0179891F7CD144005365D6 /* Assets.xcassets */, 152 | AD01798B1F7CD144005365D6 /* LaunchScreen.storyboard */, 153 | AD01798E1F7CD144005365D6 /* Info.plist */, 154 | ); 155 | path = AVPlayer; 156 | sourceTree = ""; 157 | }; 158 | AD0179961F7CD144005365D6 /* AVPlayerTests */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | AD0179971F7CD144005365D6 /* AVPlayerTests.swift */, 162 | AD0179991F7CD144005365D6 /* Info.plist */, 163 | ); 164 | path = AVPlayerTests; 165 | sourceTree = ""; 166 | }; 167 | AD0179A11F7CD144005365D6 /* AVPlayerUITests */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | AD0179A21F7CD144005365D6 /* AVPlayerUITests.swift */, 171 | AD0179A41F7CD144005365D6 /* Info.plist */, 172 | ); 173 | path = AVPlayerUITests; 174 | sourceTree = ""; 175 | }; 176 | /* End PBXGroup section */ 177 | 178 | /* Begin PBXNativeTarget section */ 179 | AD01797E1F7CD144005365D6 /* AVPlayer */ = { 180 | isa = PBXNativeTarget; 181 | buildConfigurationList = AD0179A71F7CD144005365D6 /* Build configuration list for PBXNativeTarget "AVPlayer" */; 182 | buildPhases = ( 183 | 25E9A0ACD2A81C8A253B1875 /* [CP] Check Pods Manifest.lock */, 184 | AD01797B1F7CD144005365D6 /* Sources */, 185 | AD01797C1F7CD144005365D6 /* Frameworks */, 186 | AD01797D1F7CD144005365D6 /* Resources */, 187 | CCC870842D04CBF235C85F63 /* [CP] Embed Pods Frameworks */, 188 | ); 189 | buildRules = ( 190 | ); 191 | dependencies = ( 192 | ); 193 | name = AVPlayer; 194 | productName = AVPlayer; 195 | productReference = AD01797F1F7CD144005365D6 /* AVPlayer.app */; 196 | productType = "com.apple.product-type.application"; 197 | }; 198 | AD0179921F7CD144005365D6 /* AVPlayerTests */ = { 199 | isa = PBXNativeTarget; 200 | buildConfigurationList = AD0179AA1F7CD144005365D6 /* Build configuration list for PBXNativeTarget "AVPlayerTests" */; 201 | buildPhases = ( 202 | AD01798F1F7CD144005365D6 /* Sources */, 203 | AD0179901F7CD144005365D6 /* Frameworks */, 204 | AD0179911F7CD144005365D6 /* Resources */, 205 | ); 206 | buildRules = ( 207 | ); 208 | dependencies = ( 209 | AD0179951F7CD144005365D6 /* PBXTargetDependency */, 210 | ); 211 | name = AVPlayerTests; 212 | productName = AVPlayerTests; 213 | productReference = AD0179931F7CD144005365D6 /* AVPlayerTests.xctest */; 214 | productType = "com.apple.product-type.bundle.unit-test"; 215 | }; 216 | AD01799D1F7CD144005365D6 /* AVPlayerUITests */ = { 217 | isa = PBXNativeTarget; 218 | buildConfigurationList = AD0179AD1F7CD144005365D6 /* Build configuration list for PBXNativeTarget "AVPlayerUITests" */; 219 | buildPhases = ( 220 | AD01799A1F7CD144005365D6 /* Sources */, 221 | AD01799B1F7CD144005365D6 /* Frameworks */, 222 | AD01799C1F7CD144005365D6 /* Resources */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | AD0179A01F7CD144005365D6 /* PBXTargetDependency */, 228 | ); 229 | name = AVPlayerUITests; 230 | productName = AVPlayerUITests; 231 | productReference = AD01799E1F7CD144005365D6 /* AVPlayerUITests.xctest */; 232 | productType = "com.apple.product-type.bundle.ui-testing"; 233 | }; 234 | /* End PBXNativeTarget section */ 235 | 236 | /* Begin PBXProject section */ 237 | AD0179771F7CD144005365D6 /* Project object */ = { 238 | isa = PBXProject; 239 | attributes = { 240 | LastSwiftUpdateCheck = 0900; 241 | LastUpgradeCheck = 0900; 242 | ORGANIZATIONNAME = tianjifou; 243 | TargetAttributes = { 244 | AD01797E1F7CD144005365D6 = { 245 | CreatedOnToolsVersion = 9.0; 246 | ProvisioningStyle = Manual; 247 | }; 248 | AD0179921F7CD144005365D6 = { 249 | CreatedOnToolsVersion = 9.0; 250 | ProvisioningStyle = Automatic; 251 | TestTargetID = AD01797E1F7CD144005365D6; 252 | }; 253 | AD01799D1F7CD144005365D6 = { 254 | CreatedOnToolsVersion = 9.0; 255 | ProvisioningStyle = Automatic; 256 | TestTargetID = AD01797E1F7CD144005365D6; 257 | }; 258 | }; 259 | }; 260 | buildConfigurationList = AD01797A1F7CD144005365D6 /* Build configuration list for PBXProject "AVPlayer" */; 261 | compatibilityVersion = "Xcode 8.0"; 262 | developmentRegion = en; 263 | hasScannedForEncodings = 0; 264 | knownRegions = ( 265 | en, 266 | Base, 267 | ); 268 | mainGroup = AD0179761F7CD144005365D6; 269 | productRefGroup = AD0179801F7CD144005365D6 /* Products */; 270 | projectDirPath = ""; 271 | projectRoot = ""; 272 | targets = ( 273 | AD01797E1F7CD144005365D6 /* AVPlayer */, 274 | AD0179921F7CD144005365D6 /* AVPlayerTests */, 275 | AD01799D1F7CD144005365D6 /* AVPlayerUITests */, 276 | ); 277 | }; 278 | /* End PBXProject section */ 279 | 280 | /* Begin PBXResourcesBuildPhase section */ 281 | AD01797D1F7CD144005365D6 /* Resources */ = { 282 | isa = PBXResourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | AD01798D1F7CD144005365D6 /* LaunchScreen.storyboard in Resources */, 286 | AD01798A1F7CD144005365D6 /* Assets.xcassets in Resources */, 287 | AD0179881F7CD144005365D6 /* Main.storyboard in Resources */, 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | AD0179911F7CD144005365D6 /* Resources */ = { 292 | isa = PBXResourcesBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | AD01799C1F7CD144005365D6 /* Resources */ = { 299 | isa = PBXResourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | /* End PBXResourcesBuildPhase section */ 306 | 307 | /* Begin PBXShellScriptBuildPhase section */ 308 | 25E9A0ACD2A81C8A253B1875 /* [CP] Check Pods Manifest.lock */ = { 309 | isa = PBXShellScriptBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | ); 313 | inputPaths = ( 314 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 315 | "${PODS_ROOT}/Manifest.lock", 316 | ); 317 | name = "[CP] Check Pods Manifest.lock"; 318 | outputPaths = ( 319 | "$(DERIVED_FILE_DIR)/Pods-AVPlayer-checkManifestLockResult.txt", 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | shellPath = /bin/sh; 323 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 324 | showEnvVarsInLog = 0; 325 | }; 326 | CCC870842D04CBF235C85F63 /* [CP] Embed Pods Frameworks */ = { 327 | isa = PBXShellScriptBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | ); 331 | inputPaths = ( 332 | "${SRCROOT}/Pods/Target Support Files/Pods-AVPlayer/Pods-AVPlayer-frameworks.sh", 333 | "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", 334 | "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework", 335 | "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework", 336 | "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework", 337 | "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework", 338 | "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", 339 | "${BUILT_PRODUCTS_DIR}/UITableView+FDTemplateLayoutCell/UITableView_FDTemplateLayoutCell.framework", 340 | ); 341 | name = "[CP] Embed Pods Frameworks"; 342 | outputPaths = ( 343 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework", 344 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework", 345 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework", 346 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework", 347 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework", 348 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", 349 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UITableView_FDTemplateLayoutCell.framework", 350 | ); 351 | runOnlyForDeploymentPostprocessing = 0; 352 | shellPath = /bin/sh; 353 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AVPlayer/Pods-AVPlayer-frameworks.sh\"\n"; 354 | showEnvVarsInLog = 0; 355 | }; 356 | /* End PBXShellScriptBuildPhase section */ 357 | 358 | /* Begin PBXSourcesBuildPhase section */ 359 | AD01797B1F7CD144005365D6 /* Sources */ = { 360 | isa = PBXSourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | ADCDC9461F7DE57E00996FD1 /* TJFHomeViewController.swift in Sources */, 364 | ADC82E3F1F8C649200B22ACE /* SelectScrollview.swift in Sources */, 365 | ADCDC9441F7DE55500996FD1 /* TJFBaseViewController.swift in Sources */, 366 | ADCDC9421F7DE51600996FD1 /* TJFMainTabBarViewController.swift in Sources */, 367 | AD0179851F7CD144005365D6 /* ViewController.swift in Sources */, 368 | ADCDC9401F7DDD1D00996FD1 /* TJFBaseNavigationViewController.swift in Sources */, 369 | ADCDC9481F7DE59000996FD1 /* TJFMyViewController.swift in Sources */, 370 | ADCDC94A1F7DFAC500996FD1 /* HomeTableViewCell.swift in Sources */, 371 | AD0179831F7CD144005365D6 /* AppDelegate.swift in Sources */, 372 | AD7A3CED1F99DC9600F4EA55 /* TestViewViewController.swift in Sources */, 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | AD01798F1F7CD144005365D6 /* Sources */ = { 377 | isa = PBXSourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | AD0179981F7CD144005365D6 /* AVPlayerTests.swift in Sources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | AD01799A1F7CD144005365D6 /* Sources */ = { 385 | isa = PBXSourcesBuildPhase; 386 | buildActionMask = 2147483647; 387 | files = ( 388 | AD0179A31F7CD144005365D6 /* AVPlayerUITests.swift in Sources */, 389 | ); 390 | runOnlyForDeploymentPostprocessing = 0; 391 | }; 392 | /* End PBXSourcesBuildPhase section */ 393 | 394 | /* Begin PBXTargetDependency section */ 395 | AD0179951F7CD144005365D6 /* PBXTargetDependency */ = { 396 | isa = PBXTargetDependency; 397 | target = AD01797E1F7CD144005365D6 /* AVPlayer */; 398 | targetProxy = AD0179941F7CD144005365D6 /* PBXContainerItemProxy */; 399 | }; 400 | AD0179A01F7CD144005365D6 /* PBXTargetDependency */ = { 401 | isa = PBXTargetDependency; 402 | target = AD01797E1F7CD144005365D6 /* AVPlayer */; 403 | targetProxy = AD01799F1F7CD144005365D6 /* PBXContainerItemProxy */; 404 | }; 405 | /* End PBXTargetDependency section */ 406 | 407 | /* Begin PBXVariantGroup section */ 408 | AD0179861F7CD144005365D6 /* Main.storyboard */ = { 409 | isa = PBXVariantGroup; 410 | children = ( 411 | AD0179871F7CD144005365D6 /* Base */, 412 | ); 413 | name = Main.storyboard; 414 | sourceTree = ""; 415 | }; 416 | AD01798B1F7CD144005365D6 /* LaunchScreen.storyboard */ = { 417 | isa = PBXVariantGroup; 418 | children = ( 419 | AD01798C1F7CD144005365D6 /* Base */, 420 | ); 421 | name = LaunchScreen.storyboard; 422 | sourceTree = ""; 423 | }; 424 | /* End PBXVariantGroup section */ 425 | 426 | /* Begin XCBuildConfiguration section */ 427 | AD0179A51F7CD144005365D6 /* Debug */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | ALWAYS_SEARCH_USER_PATHS = NO; 431 | CLANG_ANALYZER_NONNULL = YES; 432 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_ENABLE_MODULES = YES; 436 | CLANG_ENABLE_OBJC_ARC = YES; 437 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 438 | CLANG_WARN_BOOL_CONVERSION = YES; 439 | CLANG_WARN_COMMA = YES; 440 | CLANG_WARN_CONSTANT_CONVERSION = YES; 441 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 442 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 443 | CLANG_WARN_EMPTY_BODY = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INFINITE_RECURSION = YES; 446 | CLANG_WARN_INT_CONVERSION = YES; 447 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 449 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 450 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 451 | CLANG_WARN_STRICT_PROTOTYPES = YES; 452 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 453 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 454 | CLANG_WARN_UNREACHABLE_CODE = YES; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | CODE_SIGN_IDENTITY = "iPhone Developer"; 457 | COPY_PHASE_STRIP = NO; 458 | DEBUG_INFORMATION_FORMAT = dwarf; 459 | ENABLE_STRICT_OBJC_MSGSEND = YES; 460 | ENABLE_TESTABILITY = YES; 461 | GCC_C_LANGUAGE_STANDARD = gnu11; 462 | GCC_DYNAMIC_NO_PIC = NO; 463 | GCC_NO_COMMON_BLOCKS = YES; 464 | GCC_OPTIMIZATION_LEVEL = 0; 465 | GCC_PREPROCESSOR_DEFINITIONS = ( 466 | "DEBUG=1", 467 | "$(inherited)", 468 | ); 469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 470 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 471 | GCC_WARN_UNDECLARED_SELECTOR = YES; 472 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 473 | GCC_WARN_UNUSED_FUNCTION = YES; 474 | GCC_WARN_UNUSED_VARIABLE = YES; 475 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 476 | MTL_ENABLE_DEBUG_INFO = YES; 477 | ONLY_ACTIVE_ARCH = YES; 478 | SDKROOT = iphoneos; 479 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 480 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 481 | }; 482 | name = Debug; 483 | }; 484 | AD0179A61F7CD144005365D6 /* Release */ = { 485 | isa = XCBuildConfiguration; 486 | buildSettings = { 487 | ALWAYS_SEARCH_USER_PATHS = NO; 488 | CLANG_ANALYZER_NONNULL = YES; 489 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 490 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 491 | CLANG_CXX_LIBRARY = "libc++"; 492 | CLANG_ENABLE_MODULES = YES; 493 | CLANG_ENABLE_OBJC_ARC = YES; 494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 495 | CLANG_WARN_BOOL_CONVERSION = YES; 496 | CLANG_WARN_COMMA = YES; 497 | CLANG_WARN_CONSTANT_CONVERSION = YES; 498 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 499 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 500 | CLANG_WARN_EMPTY_BODY = YES; 501 | CLANG_WARN_ENUM_CONVERSION = YES; 502 | CLANG_WARN_INFINITE_RECURSION = YES; 503 | CLANG_WARN_INT_CONVERSION = YES; 504 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 505 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 506 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 507 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 508 | CLANG_WARN_STRICT_PROTOTYPES = YES; 509 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 510 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 511 | CLANG_WARN_UNREACHABLE_CODE = YES; 512 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 513 | CODE_SIGN_IDENTITY = "iPhone Developer"; 514 | COPY_PHASE_STRIP = NO; 515 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 516 | ENABLE_NS_ASSERTIONS = NO; 517 | ENABLE_STRICT_OBJC_MSGSEND = YES; 518 | GCC_C_LANGUAGE_STANDARD = gnu11; 519 | GCC_NO_COMMON_BLOCKS = YES; 520 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 521 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 522 | GCC_WARN_UNDECLARED_SELECTOR = YES; 523 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 524 | GCC_WARN_UNUSED_FUNCTION = YES; 525 | GCC_WARN_UNUSED_VARIABLE = YES; 526 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 527 | MTL_ENABLE_DEBUG_INFO = NO; 528 | SDKROOT = iphoneos; 529 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 530 | VALIDATE_PRODUCT = YES; 531 | }; 532 | name = Release; 533 | }; 534 | AD0179A81F7CD144005365D6 /* Debug */ = { 535 | isa = XCBuildConfiguration; 536 | baseConfigurationReference = 8374F277B246C84259B2D615 /* Pods-AVPlayer.debug.xcconfig */; 537 | buildSettings = { 538 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 539 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 540 | CODE_SIGN_STYLE = Manual; 541 | DEVELOPMENT_TEAM = 6GA5676ZM3; 542 | INFOPLIST_FILE = AVPlayer/Info.plist; 543 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 544 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 545 | PRODUCT_BUNDLE_IDENTIFIER = tianjifou.AVPlayer; 546 | PRODUCT_NAME = "$(TARGET_NAME)"; 547 | PROVISIONING_PROFILE = "e084a94c-42c8-4734-b71d-695f00d31803"; 548 | PROVISIONING_PROFILE_SPECIFIER = wanjiaWildcard; 549 | SWIFT_VERSION = 4.0; 550 | TARGETED_DEVICE_FAMILY = "1,2"; 551 | }; 552 | name = Debug; 553 | }; 554 | AD0179A91F7CD144005365D6 /* Release */ = { 555 | isa = XCBuildConfiguration; 556 | baseConfigurationReference = 658A303F8BBF9667910CADD2 /* Pods-AVPlayer.release.xcconfig */; 557 | buildSettings = { 558 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 559 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 560 | CODE_SIGN_STYLE = Manual; 561 | DEVELOPMENT_TEAM = 6GA5676ZM3; 562 | INFOPLIST_FILE = AVPlayer/Info.plist; 563 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 564 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 565 | PRODUCT_BUNDLE_IDENTIFIER = tianjifou.AVPlayer; 566 | PRODUCT_NAME = "$(TARGET_NAME)"; 567 | PROVISIONING_PROFILE = "e084a94c-42c8-4734-b71d-695f00d31803"; 568 | PROVISIONING_PROFILE_SPECIFIER = wanjiaWildcard; 569 | SWIFT_VERSION = 4.0; 570 | TARGETED_DEVICE_FAMILY = "1,2"; 571 | }; 572 | name = Release; 573 | }; 574 | AD0179AB1F7CD144005365D6 /* Debug */ = { 575 | isa = XCBuildConfiguration; 576 | buildSettings = { 577 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 578 | BUNDLE_LOADER = "$(TEST_HOST)"; 579 | CODE_SIGN_STYLE = Automatic; 580 | DEVELOPMENT_TEAM = 2Z9X5ENNPW; 581 | INFOPLIST_FILE = AVPlayerTests/Info.plist; 582 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 583 | PRODUCT_BUNDLE_IDENTIFIER = tianjifou.AVPlayerTests; 584 | PRODUCT_NAME = "$(TARGET_NAME)"; 585 | SWIFT_VERSION = 4.0; 586 | TARGETED_DEVICE_FAMILY = "1,2"; 587 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AVPlayer.app/AVPlayer"; 588 | }; 589 | name = Debug; 590 | }; 591 | AD0179AC1F7CD144005365D6 /* Release */ = { 592 | isa = XCBuildConfiguration; 593 | buildSettings = { 594 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 595 | BUNDLE_LOADER = "$(TEST_HOST)"; 596 | CODE_SIGN_STYLE = Automatic; 597 | DEVELOPMENT_TEAM = 2Z9X5ENNPW; 598 | INFOPLIST_FILE = AVPlayerTests/Info.plist; 599 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 600 | PRODUCT_BUNDLE_IDENTIFIER = tianjifou.AVPlayerTests; 601 | PRODUCT_NAME = "$(TARGET_NAME)"; 602 | SWIFT_VERSION = 4.0; 603 | TARGETED_DEVICE_FAMILY = "1,2"; 604 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AVPlayer.app/AVPlayer"; 605 | }; 606 | name = Release; 607 | }; 608 | AD0179AE1F7CD144005365D6 /* Debug */ = { 609 | isa = XCBuildConfiguration; 610 | buildSettings = { 611 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 612 | CODE_SIGN_STYLE = Automatic; 613 | DEVELOPMENT_TEAM = 2Z9X5ENNPW; 614 | INFOPLIST_FILE = AVPlayerUITests/Info.plist; 615 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 616 | PRODUCT_BUNDLE_IDENTIFIER = tianjifou.AVPlayerUITests; 617 | PRODUCT_NAME = "$(TARGET_NAME)"; 618 | SWIFT_VERSION = 4.0; 619 | TARGETED_DEVICE_FAMILY = "1,2"; 620 | TEST_TARGET_NAME = AVPlayer; 621 | }; 622 | name = Debug; 623 | }; 624 | AD0179AF1F7CD144005365D6 /* Release */ = { 625 | isa = XCBuildConfiguration; 626 | buildSettings = { 627 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 628 | CODE_SIGN_STYLE = Automatic; 629 | DEVELOPMENT_TEAM = 2Z9X5ENNPW; 630 | INFOPLIST_FILE = AVPlayerUITests/Info.plist; 631 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 632 | PRODUCT_BUNDLE_IDENTIFIER = tianjifou.AVPlayerUITests; 633 | PRODUCT_NAME = "$(TARGET_NAME)"; 634 | SWIFT_VERSION = 4.0; 635 | TARGETED_DEVICE_FAMILY = "1,2"; 636 | TEST_TARGET_NAME = AVPlayer; 637 | }; 638 | name = Release; 639 | }; 640 | /* End XCBuildConfiguration section */ 641 | 642 | /* Begin XCConfigurationList section */ 643 | AD01797A1F7CD144005365D6 /* Build configuration list for PBXProject "AVPlayer" */ = { 644 | isa = XCConfigurationList; 645 | buildConfigurations = ( 646 | AD0179A51F7CD144005365D6 /* Debug */, 647 | AD0179A61F7CD144005365D6 /* Release */, 648 | ); 649 | defaultConfigurationIsVisible = 0; 650 | defaultConfigurationName = Release; 651 | }; 652 | AD0179A71F7CD144005365D6 /* Build configuration list for PBXNativeTarget "AVPlayer" */ = { 653 | isa = XCConfigurationList; 654 | buildConfigurations = ( 655 | AD0179A81F7CD144005365D6 /* Debug */, 656 | AD0179A91F7CD144005365D6 /* Release */, 657 | ); 658 | defaultConfigurationIsVisible = 0; 659 | defaultConfigurationName = Release; 660 | }; 661 | AD0179AA1F7CD144005365D6 /* Build configuration list for PBXNativeTarget "AVPlayerTests" */ = { 662 | isa = XCConfigurationList; 663 | buildConfigurations = ( 664 | AD0179AB1F7CD144005365D6 /* Debug */, 665 | AD0179AC1F7CD144005365D6 /* Release */, 666 | ); 667 | defaultConfigurationIsVisible = 0; 668 | defaultConfigurationName = Release; 669 | }; 670 | AD0179AD1F7CD144005365D6 /* Build configuration list for PBXNativeTarget "AVPlayerUITests" */ = { 671 | isa = XCConfigurationList; 672 | buildConfigurations = ( 673 | AD0179AE1F7CD144005365D6 /* Debug */, 674 | AD0179AF1F7CD144005365D6 /* Release */, 675 | ); 676 | defaultConfigurationIsVisible = 0; 677 | defaultConfigurationName = Release; 678 | }; 679 | /* End XCConfigurationList section */ 680 | }; 681 | rootObject = AD0179771F7CD144005365D6 /* Project object */; 682 | } 683 | -------------------------------------------------------------------------------- /AVPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/28. 6 | // Copyright © 2017年 tianjifou. 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?.rootViewController = TJFMainTabBarViewController() 21 | 22 | 23 | 24 | return true 25 | } 26 | 27 | func applicationWillResignActive(_ application: UIApplication) { 28 | // 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. 29 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 30 | } 31 | 32 | func applicationDidEnterBackground(_ application: UIApplication) { 33 | // 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. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | func applicationWillEnterForeground(_ application: UIApplication) { 38 | // 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. 39 | } 40 | 41 | func applicationDidBecomeActive(_ application: UIApplication) { 42 | // 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. 43 | } 44 | 45 | func applicationWillTerminate(_ application: UIApplication) { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | 50 | } 51 | public extension UIDevice { 52 | 53 | var modelName: String { 54 | var systemInfo = utsname() 55 | uname(&systemInfo) 56 | let machineMirror = Mirror(reflecting: systemInfo.machine) 57 | let identifier = machineMirror.children.reduce("") { identifier, element in 58 | guard let value = element.value as? Int8, value != 0 else { return identifier } 59 | return identifier + String(UnicodeScalar(UInt8(value))) 60 | } 61 | 62 | switch identifier { 63 | case "iPod1,1": return "iPod Touch 1" 64 | case "iPod2,1": return "iPod Touch 2" 65 | case "iPod3,1": return "iPod Touch 3" 66 | case "iPod4,1": return "iPod Touch 4" 67 | case "iPod5,1": return "iPod Touch (5 Gen)" 68 | case "iPod7,1": return "iPod Touch 6" 69 | 70 | case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4" 71 | case "iPhone4,1": return "iPhone 4s" 72 | case "iPhone5,1": return "iPhone 5" 73 | case "iPhone5,2": return "iPhone 5 (GSM+CDMA)" 74 | case "iPhone5,3": return "iPhone 5c (GSM)" 75 | case "iPhone5,4": return "iPhone 5c (GSM+CDMA)" 76 | case "iPhone6,1": return "iPhone 5s (GSM)" 77 | case "iPhone6,2": return "iPhone 5s (GSM+CDMA)" 78 | case "iPhone7,2": return "iPhone 6" 79 | case "iPhone7,1": return "iPhone 6 Plus" 80 | case "iPhone8,1": return "iPhone 6s" 81 | case "iPhone8,2": return "iPhone 6s Plus" 82 | case "iPhone8,4": return "iPhone SE" 83 | case "iPhone9,1": return "国行、日版、港行iPhone 7" 84 | case "iPhone9,2": return "港行、国行iPhone 7 Plus" 85 | case "iPhone9,3": return "美版、台版iPhone 7" 86 | case "iPhone9,4": return "美版、台版iPhone 7 Plus" 87 | case "iPhone10,1","iPhone10,4": return "iPhone 8" 88 | case "iPhone10,2","iPhone10,5": return "iPhone 8 Plus" 89 | case "iPhone10,3","iPhone10,6": return "iPhone X" 90 | 91 | case "iPad1,1": return "iPad" 92 | case "iPad1,2": return "iPad 3G" 93 | case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad 2" 94 | case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad Mini" 95 | case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad 3" 96 | case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad 4" 97 | case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air" 98 | case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad Mini 2" 99 | case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad Mini 3" 100 | case "iPad5,1", "iPad5,2": return "iPad Mini 4" 101 | case "iPad5,3", "iPad5,4": return "iPad Air 2" 102 | case "iPad6,3", "iPad6,4": return "iPad Pro 9.7" 103 | case "iPad6,7", "iPad6,8": return "iPad Pro 12.9" 104 | case "AppleTV2,1": return "Apple TV 2" 105 | case "AppleTV3,1","AppleTV3,2": return "Apple TV 3" 106 | case "AppleTV5,3": return "Apple TV 4" 107 | case "i386", "x86_64": return "Simulator" 108 | default: return identifier 109 | } 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/back_leftButton.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "back_leftButton@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "back_leftButton@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/back_leftButton.imageset/back_leftButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/AVPlayer/Assets.xcassets/back_leftButton.imageset/back_leftButton@2x.png -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/back_leftButton.imageset/back_leftButton@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/AVPlayer/Assets.xcassets/back_leftButton.imageset/back_leftButton@3x.png -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_gzt1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_gzt1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_gzt1.imageset/icon_gzt1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/AVPlayer/Assets.xcassets/icon_gzt1.imageset/icon_gzt1.png -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_gzt2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_gzt2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_gzt2.imageset/icon_gzt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/AVPlayer/Assets.xcassets/icon_gzt2.imageset/icon_gzt2.png -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_wd1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_wd1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_wd1.imageset/icon_wd1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/AVPlayer/Assets.xcassets/icon_wd1.imageset/icon_wd1.png -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_wd2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_wd2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AVPlayer/Assets.xcassets/icon_wd2.imageset/icon_wd2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/AVPlayer/Assets.xcassets/icon_wd2.imageset/icon_wd2.png -------------------------------------------------------------------------------- /AVPlayer/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 | 25 | 26 | -------------------------------------------------------------------------------- /AVPlayer/Base.lproj/Main.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 | 25 | -------------------------------------------------------------------------------- /AVPlayer/HomeTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeTableViewCell.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/29. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class HomeTableViewCell: UITableViewCell { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | // Initialization code 16 | } 17 | 18 | override func setSelected(_ selected: Bool, animated: Bool) { 19 | super.setSelected(selected, animated: animated) 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /AVPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /AVPlayer/SelectScrollview.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelectScrollview.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/10/10. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Masonry 11 | class SelectScrollview:UIView{ 12 | var viewControllers:[UIViewController]? 13 | var arrTitle:[String]? 14 | fileprivate static let btnTag = 100 15 | fileprivate let screenWidth = UIScreen.main.bounds.size.width 16 | fileprivate var isClick = false 17 | fileprivate var kWidthArr:[CGFloat] = [] 18 | fileprivate var bWidthArr:[CGFloat] = [] 19 | fileprivate var kPointArr:[CGFloat] = [] 20 | fileprivate var bPointArr:[CGFloat] = [] 21 | fileprivate var btnWidth:[CGFloat] = [] 22 | fileprivate var btnCenter:[CGFloat] = [] 23 | 24 | override init(frame: CGRect) { 25 | super.init(frame: frame) 26 | self.backgroundColor = UIColor.clear 27 | } 28 | 29 | required init?(coder aDecoder: NSCoder) { 30 | fatalError("init(coder:) has not been implemented") 31 | } 32 | 33 | override func layoutSubviews() { 34 | guard let viewControllers = viewControllers,viewControllers.count > 0 else {return} 35 | super.layoutSubviews() 36 | let width = CGFloat(viewControllers.count)*screenWidth 37 | let height = self.bounds.size.height - 88 38 | viewConrtollerScroll.contentSize = CGSize.init(width: width, height: height) 39 | 40 | for (_,vc) in dicForVC { 41 | vc.view.mas_updateConstraints({ (make) in 42 | make!.size.mas_equalTo()(CGSize.init(width: self.screenWidth, height: self.bounds.size.height - 44)) }) 43 | } 44 | } 45 | 46 | 47 | func createUI() { 48 | guard let viewControllers = viewControllers,viewControllers.count > 0 else {return} 49 | self.addSubview(topScrollView) 50 | topScrollView.mas_makeConstraints { (make) in 51 | make!.left.equalTo()(10) 52 | make!.right.equalTo()(-10) 53 | make!.top.equalTo() 54 | make!.height.equalTo()(44) 55 | } 56 | createtopScrollBtn() 57 | topScrollView.addSubview(topAnotherScrollView) 58 | createtopAnotherScrollBtn() 59 | topAnotherScrollView.addSubview(bottomView) 60 | bottomView.mas_makeConstraints { (make) in 61 | make!.left.right().bottom().equalTo() 62 | make!.height.equalTo()(4) 63 | } 64 | let width = CGFloat(viewControllers.count)*screenWidth 65 | let height = self.bounds.size.height - 88 66 | viewConrtollerScroll.contentSize = CGSize.init(width: width, height: height) 67 | self.addSubview(viewConrtollerScroll) 68 | viewConrtollerScroll.mas_makeConstraints { (make) in 69 | make!.left.right().bottom().equalTo() 70 | make!.top.equalTo()(self.topScrollView.mas_bottom) 71 | } 72 | xianXinHanShu() 73 | self.currentPage = 0 74 | } 75 | 76 | public func xianXinHanShu() { 77 | guard let arrTitle = arrTitle else {return} 78 | 79 | for index in 0.. 0 else {return} 185 | 186 | let widthFirst = (arrTitle[0] as NSString).size(withAttributes: [NSAttributedStringKey.font:UIFont.systemFont(ofSize: 13)]).width+4 187 | topAnotherScrollView.mas_makeConstraints { (make) in 188 | make!.top.equalTo()(0) 189 | make!.centerX.equalTo()(self.topScrollView.mas_left)!.offset()(widthFirst/2) 190 | make!.width.equalTo()(widthFirst) 191 | make!.height.equalTo()(44) 192 | } 193 | var tempBtn:UIButton? 194 | var widthTotal:CGFloat = 0 195 | for title in arrTitle { 196 | let btn = UIButton() 197 | btn.setTitle(title, for: .normal) 198 | btn.setTitleColor(UIColor.blue, for: .normal) 199 | btn.titleLabel?.font = UIFont.systemFont(ofSize: 13) 200 | btn.titleLabel?.textAlignment = .center 201 | topAnotherScrollView.addSubview(btn) 202 | let width = (title as NSString).size(withAttributes: [NSAttributedStringKey.font:UIFont.systemFont(ofSize: 13)]).width+4 203 | widthTotal += width + 10 204 | btn.mas_makeConstraints({ (make) in 205 | if let tempBtn = tempBtn { 206 | make!.left.equalTo()(tempBtn.mas_right)!.offset()(10) 207 | }else { 208 | make!.left.equalTo()(self.topScrollView.mas_left) 209 | } 210 | make!.top.equalTo() 211 | make!.width.equalTo()(width) 212 | make!.height.equalTo()(44) 213 | }) 214 | tempBtn = btn 215 | } 216 | 217 | } 218 | 219 | 220 | lazy var topAnotherScrollView:UIView = { 221 | let scroll = UIView() 222 | scroll.clipsToBounds = true 223 | return scroll 224 | }() 225 | 226 | lazy var bottomView:UIView = { 227 | let view = UIView() 228 | view.backgroundColor = UIColor.blue 229 | return view 230 | }() 231 | 232 | lazy var viewConrtollerScroll:UIScrollView = { 233 | let scroll = UIScrollView() 234 | scroll.showsHorizontalScrollIndicator = true 235 | scroll.alwaysBounceHorizontal = true 236 | scroll.delegate = self 237 | scroll.isPagingEnabled = true 238 | return scroll 239 | }() 240 | 241 | fileprivate var dicForVC:[Int:UIViewController] = [:] 242 | 243 | fileprivate var currentPage:Int = -1 { 244 | didSet { 245 | if let vc = self.viewControllers { 246 | guard let _ = dicForVC[currentPage] else { 247 | dicForVC[currentPage] = vc[currentPage] 248 | self.viewConrtollerScroll.addSubview(vc[currentPage].view) 249 | vc[currentPage].view.mas_makeConstraints({ (make) in 250 | make!.left.equalTo()(CGFloat(self.currentPage)*self.screenWidth) 251 | make!.top.equalTo() 252 | make!.size.mas_equalTo()(CGSize.init(width: self.screenWidth, height: self.bounds.size.height - 44)) 253 | }) 254 | 255 | return 256 | } 257 | } 258 | } 259 | } 260 | 261 | fileprivate func widthInfor(offsetX:CGFloat) -> CGFloat { 262 | if kPointArr.count == 0 || bPointArr.count == 0{ 263 | return 0 264 | } 265 | var index = Int(offsetX*1.999/self.frame.width) 266 | if index >= kPointArr.count { 267 | index = kPointArr.count - 1 268 | } 269 | let k = kWidthArr[index] 270 | let b = bWidthArr[index] 271 | return k*offsetX + b 272 | } 273 | 274 | fileprivate func centerInfor(offsetX:CGFloat) -> CGFloat { 275 | if kPointArr.count == 0 || bPointArr.count == 0{ 276 | return 0 277 | } 278 | var index = Int(offsetX*1.999/self.frame.width) 279 | if index >= kPointArr.count { 280 | index = kPointArr.count - 1 281 | } 282 | 283 | let k = kPointArr[index] 284 | let b = bPointArr[index] 285 | 286 | return k*offsetX + b 287 | } 288 | } 289 | 290 | extension SelectScrollview: UIScrollViewDelegate { 291 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 292 | if scrollView == viewConrtollerScroll { 293 | if scrollView.contentOffset.x < 0 || scrollView.contentOffset.x > scrollView.contentSize.width - topScrollView.frame.width { 294 | return 295 | } 296 | self.currentPage = Int((scrollView.contentOffset.x + screenWidth/2)/screenWidth) 297 | if isClick { 298 | isClick = false 299 | return 300 | } 301 | 302 | topAnotherScrollView.mas_updateConstraints { (make) in 303 | make!.centerX.equalTo()(self.topScrollView.mas_left)!.offset()(self.centerInfor(offsetX: scrollView.contentOffset.x)) 304 | make!.width.equalTo()(self.widthInfor(offsetX: scrollView.contentOffset.x)) 305 | } 306 | let btnCenterX = self.centerInfor(offsetX: scrollView.contentOffset.x) 307 | let topScrollWidth = topScrollView.frame.width 308 | let topScrollConsizeWidth = topScrollView.contentSize.width 309 | if btnCenterX < topScrollWidth/2 { 310 | topScrollView.setContentOffset(CGPoint.init(x: 0, y: 0), animated: true) 311 | }else if btnCenterX + topScrollWidth/2 < topScrollConsizeWidth { 312 | topScrollView.setContentOffset(CGPoint.init(x: btnCenterX-topScrollWidth/2, y: 0), animated: true) 313 | 314 | }else { 315 | topScrollView.setContentOffset(CGPoint.init(x: topScrollConsizeWidth-topScrollWidth, y: 0), animated: true) 316 | } 317 | 318 | } 319 | } 320 | 321 | 322 | } 323 | 324 | -------------------------------------------------------------------------------- /AVPlayer/TJFBaseNavigationViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TJFBaseNavigationViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/29. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TJFBaseNavigationViewController: UINavigationController,UIGestureRecognizerDelegate,UINavigationControllerDelegate { 12 | var isPushing: Bool = false 13 | typealias CustomLeftBackButtonAction = (() -> Void) 14 | var clickAction:CustomLeftBackButtonAction? 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | self.interactivePopGestureRecognizer?.delegate = self 18 | self.delegate = self 19 | interactivePopGestureRecognizer?.isEnabled = true 20 | self.navigationBar.isTranslucent = false 21 | } 22 | override func pushViewController(_ viewController: UIViewController, animated: Bool) { 23 | if isPushing { 24 | return 25 | } else { 26 | isPushing = true 27 | } 28 | if viewController.navigationItem.leftBarButtonItem == nil, viewControllers.count > 0{ 29 | viewController.navigationItem.setLeftBarButton(customLeftBackButton(clickAction: nil), animated: true) 30 | } 31 | super.pushViewController(viewController, animated: animated) 32 | } 33 | 34 | func getScreenEdgePanGestureRecognizer() -> UIScreenEdgePanGestureRecognizer? { 35 | if let gestureRecognizers = view.gestureRecognizers { 36 | 37 | for ges in gestureRecognizers { 38 | if ges is UIScreenEdgePanGestureRecognizer { 39 | return ges as? UIScreenEdgePanGestureRecognizer 40 | } 41 | } 42 | } 43 | return nil 44 | } 45 | func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 46 | if gestureRecognizer == interactivePopGestureRecognizer { 47 | if viewControllers.count == 1 || 48 | topViewController?.presentedViewController != nil { 49 | return false 50 | } 51 | } 52 | return true 53 | } 54 | func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { 55 | isPushing = false 56 | } 57 | func customLeftBackButton(clickAction: CustomLeftBackButtonAction?) -> UIBarButtonItem { 58 | self.clickAction = clickAction 59 | let button = UIButton(type: .custom) 60 | button.frame = CGRect(x: 0, y: 0, width: 30.0, height: 18.0) 61 | button.addTarget(self, action: #selector(clickEvent), for: .touchUpInside) 62 | 63 | button.setImage(UIImage(named:"back_leftButton"), for: .normal) 64 | // 让按钮内部的所有内容左对齐 65 | button.contentHorizontalAlignment = .left 66 | // 让按钮的内容往左边偏移10 67 | button.contentEdgeInsets = UIEdgeInsetsMake(0, -5, 0, 0) 68 | let backButton = UIBarButtonItem(customView: button) 69 | return backButton 70 | } 71 | 72 | @objc func clickEvent(){ 73 | if let clickAction = clickAction { 74 | clickAction() 75 | } else { 76 | _ = self.popViewController(animated: true) 77 | } 78 | } 79 | 80 | override func didReceiveMemoryWarning() { 81 | super.didReceiveMemoryWarning() 82 | // Dispose of any resources that can be recreated. 83 | } 84 | 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /AVPlayer/TJFBaseViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TJFBaseViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/29. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TJFBaseViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /AVPlayer/TJFHomeViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TJFHomeViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/29. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Masonry 11 | let statusBarHeight = UIApplication.shared.statusBarFrame.size.height 12 | var isIPHONE_X: Bool { 13 | return UIScreen.instancesRespond(to: #selector(getter: UIDynamicItem.bounds)) ? CGSize(width: 375, height: 812).equalTo(UIScreen.main.bounds.size) : false 14 | } 15 | class TJFHomeViewController: UIViewController { 16 | var botomView:SelectScrollview! 17 | let barHeight = isIPHONE_X ? -88 : -44 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | self.navigationController?.navigationBar.shadowImage = UIImage() 21 | self.title = "首页" 22 | self.view.backgroundColor = UIColor.white 23 | // Do any additional setup after loading the view. 24 | botomView = SelectScrollview() 25 | botomView.arrTitle = ["首页","电影","电视剧","动漫","综艺","首页","电影","电视剧","动漫","综艺","首页","电影","电视剧","动漫","综艺"] 26 | var arr:[UIViewController] = [] 27 | for index in 0.. 0 { 65 | self.navigationController?.setNavigationBarHidden(true, animated: true) 66 | setStatusBackgroundColor(true) 67 | self.view.layoutIfNeeded() 68 | self.botomView.mas_updateConstraints({ (make) in 69 | make!.top.equalTo()(statusBarHeight) 70 | }) 71 | 72 | UIView.animate(withDuration: 0.3, animations: { 73 | self.view.layoutIfNeeded() 74 | }) 75 | }else { 76 | self.navigationController?.setNavigationBarHidden(false, animated: true) 77 | setStatusBackgroundColor(false) 78 | self.view.layoutIfNeeded() 79 | self.botomView.mas_updateConstraints({ (make) in 80 | make!.top.equalTo()(0) 81 | }) 82 | 83 | UIView.animate(withDuration: 0.3, animations: { 84 | self.view.layoutIfNeeded() 85 | }) 86 | } 87 | } 88 | func setStatusBackgroundColor(_ isHiden:Bool){ 89 | if let statusBar = (UIApplication.shared.value(forKey: "statusBarWindow") as? UIView)?.value(forKey: "statusBar") as? UIView{ 90 | if statusBar.responds(to: #selector(setter: UIView.backgroundColor)){ 91 | if isHiden{ 92 | statusBar.backgroundColor = UIColor.white 93 | }else{ 94 | statusBar.backgroundColor = UIColor.clear 95 | } 96 | 97 | } 98 | } 99 | } 100 | 101 | } 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /AVPlayer/TJFMainTabBarViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TJFMainTabBarViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/29. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TJFMainTabBarViewController: UITabBarController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | let firstVC = TJFHomeViewController() 16 | self.setTabbarItem(tabBarItem: firstVC.tabBarItem, title: "首页", size: 16, selectImage:"icon_gzt2", selectTitleColor: UIColor.blue, normalImage: "icon_gzt1", normalTitleColor: UIColor.black) 17 | let nav1 = TJFBaseNavigationViewController.init(rootViewController: firstVC) 18 | let secondVC = TJFMyViewController() 19 | secondVC.title = "个人中心" 20 | self.setTabbarItem(tabBarItem: secondVC.tabBarItem, title: "个人中心", size: 16, selectImage: "icon_wd2", selectTitleColor: UIColor.blue, normalImage: "icon_wd1", normalTitleColor: UIColor.black) 21 | let nav2 = TJFBaseNavigationViewController.init(rootViewController: secondVC) 22 | 23 | self.viewControllers = [nav1,nav2] 24 | } 25 | 26 | func setTabbarItem(tabBarItem: UITabBarItem,title:String,size:CGFloat,selectImage:String,selectTitleColor:UIColor,normalImage:String,normalTitleColor:UIColor) { 27 | // tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:normalTitleColor,NSAttributedStringKey.font: UIFont.systemFont(ofSize: size)], for: .normal) 28 | // tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:selectTitleColor,NSAttributedStringKey.font:UIFont.systemFont(ofSize: size)], for: .selected) 29 | tabBarItem.title = title 30 | tabBarItem.image = UIImage.init(named: normalImage) 31 | tabBarItem.selectedImage = UIImage.init(named: selectImage) 32 | 33 | } 34 | 35 | override func didReceiveMemoryWarning() { 36 | super.didReceiveMemoryWarning() 37 | 38 | } 39 | 40 | 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /AVPlayer/TJFMyViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TJFMyViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/29. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TJFMyViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | self.view.backgroundColor = UIColor.clear 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /AVPlayer/TestViewViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestViewViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/10/20. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Masonry 11 | class TestViewViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | 18 | let btn = UIButton() 19 | btn.backgroundColor = UIColor.blue 20 | btn.addTarget(self, action: #selector(test), for: .touchUpInside) 21 | self.view.addSubview(btn) 22 | 23 | btn.mas_makeConstraints { (make) in 24 | make!.width.mas_equalTo()(CGSize.init(width: 100, height: 50)) 25 | make!.center.equalTo() 26 | } 27 | } 28 | @objc func test(){ 29 | 30 | self.dismiss(animated: false, completion: nil) 31 | UIApplication.shared.delegate?.window??.subviews.forEach({ (view) in 32 | print(Unmanaged.passUnretained(view).toOpaque()) 33 | view.removeFromSuperview() 34 | }) 35 | UIApplication.shared.delegate?.window??.rootViewController = TJFHomeViewController() 36 | 37 | 38 | } 39 | override func didReceiveMemoryWarning() { 40 | super.didReceiveMemoryWarning() 41 | // Dispose of any resources that can be recreated. 42 | } 43 | 44 | deinit { 45 | print("释放TestViewViewController") 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /AVPlayer/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // AVPlayer 4 | // 5 | // Created by 天机否 on 2017/9/28. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | @objc 11 | protocol NavBarHideDelegate:NSObjectProtocol { 12 | @objc optional func scrollViewDidScrollForNavBarHide(_ scrollView: UIScrollView) 13 | } 14 | class ViewController: UIViewController { 15 | var homeTable:UITableView! 16 | weak var delegate:NavBarHideDelegate? 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | // Do any additional setup after loading the view, typically from a nib. 20 | 21 | self.view.backgroundColor = UIColor.white 22 | // Do any additional setup after loading the view. 23 | homeTable = UITableView() 24 | homeTable.delegate = self 25 | homeTable.dataSource = self 26 | homeTable.estimatedRowHeight = 0 27 | homeTable.rowHeight = 44 28 | homeTable.separatorStyle = .none 29 | homeTable.backgroundColor = UIColor.brown 30 | homeTable.register(HomeTableViewCell.self, forCellReuseIdentifier: "HomeTableViewCell") 31 | self.view.addSubview(homeTable) 32 | 33 | homeTable.mas_makeConstraints { (make) in 34 | make!.left.top().right().bottom().equalTo() 35 | } 36 | } 37 | 38 | override func didReceiveMemoryWarning() { 39 | super.didReceiveMemoryWarning() 40 | // Dispose of any resources that can be recreated. 41 | } 42 | 43 | 44 | } 45 | extension ViewController:UITableViewDelegate,UITableViewDataSource { 46 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 47 | return 100 48 | } 49 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 50 | let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell") as! HomeTableViewCell 51 | cell.backgroundColor = UIColor.red 52 | 53 | return cell 54 | } 55 | func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 56 | return 0.001 57 | } 58 | } 59 | extension ViewController:UIScrollViewDelegate { 60 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 61 | self.delegate?.scrollViewDidScrollForNavBarHide!(scrollView) 62 | } 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /AVPlayerTests/AVPlayerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AVPlayerTests.swift 3 | // AVPlayerTests 4 | // 5 | // Created by 天机否 on 2017/9/28. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import AVPlayer 11 | 12 | class AVPlayerTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /AVPlayerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /AVPlayerUITests/AVPlayerUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AVPlayerUITests.swift 3 | // AVPlayerUITests 4 | // 5 | // Created by 天机否 on 2017/9/28. 6 | // Copyright © 2017年 tianjifou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class AVPlayerUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /AVPlayerUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | 2 | platform :ios, "8.0" 3 | 4 | target ‘AVPlayer’ do 5 | inhibit_all_warnings! 6 | use_frameworks! 7 | pod 'MJRefresh', '3.1.13' 8 | pod 'SDWebImage', '3.7.5' 9 | pod 'UITableView+FDTemplateLayoutCell', '1.6' 10 | pod 'IQKeyboardManager', '3.3.7' 11 | pod 'Masonry', '1.0.1' 12 | pod 'ObjectMapper', '2.1.0' 13 | pod ‘AFNetworking’,’3.0.4’ 14 | 15 | end 16 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (3.0.4): 3 | - AFNetworking/NSURLSession (= 3.0.4) 4 | - AFNetworking/Reachability (= 3.0.4) 5 | - AFNetworking/Security (= 3.0.4) 6 | - AFNetworking/Serialization (= 3.0.4) 7 | - AFNetworking/UIKit (= 3.0.4) 8 | - AFNetworking/NSURLSession (3.0.4): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (3.0.4) 13 | - AFNetworking/Security (3.0.4) 14 | - AFNetworking/Serialization (3.0.4) 15 | - AFNetworking/UIKit (3.0.4): 16 | - AFNetworking/NSURLSession 17 | - IQKeyboardManager (3.3.7) 18 | - Masonry (1.0.1) 19 | - MJRefresh (3.1.13) 20 | - ObjectMapper (2.1.0) 21 | - SDWebImage (3.7.5): 22 | - SDWebImage/Core (= 3.7.5) 23 | - SDWebImage/Core (3.7.5) 24 | - "UITableView+FDTemplateLayoutCell (1.6)" 25 | 26 | DEPENDENCIES: 27 | - AFNetworking (= 3.0.4) 28 | - IQKeyboardManager (= 3.3.7) 29 | - Masonry (= 1.0.1) 30 | - MJRefresh (= 3.1.13) 31 | - ObjectMapper (= 2.1.0) 32 | - SDWebImage (= 3.7.5) 33 | - "UITableView+FDTemplateLayoutCell (= 1.6)" 34 | 35 | SPEC REPOS: 36 | https://github.com/cocoapods/specs.git: 37 | - AFNetworking 38 | - IQKeyboardManager 39 | - Masonry 40 | - MJRefresh 41 | - ObjectMapper 42 | - SDWebImage 43 | - "UITableView+FDTemplateLayoutCell" 44 | 45 | SPEC CHECKSUMS: 46 | AFNetworking: a0075feb321559dc78d9d85b55d11caa19eabb93 47 | IQKeyboardManager: 249c3946acf61345c18b038eb50863fe2793e3a8 48 | Masonry: a1a931a0d08870ed8ae415a2ea5ea68ebcac77df 49 | MJRefresh: 56a28aa628c9895e97a518dabaecf70b18f92f32 50 | ObjectMapper: e5e0f8aef8590fc2ddcde7f27eddb255863ee6e9 51 | SDWebImage: 69c6303e3348fba97e03f65d65d4fbc26740f461 52 | "UITableView+FDTemplateLayoutCell": 5c949b4a5059c404b442926c0e80f81d10a2d66f 53 | 54 | PODFILE CHECKSUM: 9b8209349db4f818029813daa91ea2d6a5aecd9f 55 | 56 | COCOAPODS: 1.5.3 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 仿乐视视频、腾讯视频分段选择栏 2 | 3 | 选择栏的字随着滑动的手势,会和下面的下划线一起呈现形变。乐视视频的效果,是我发现所有主流APP中效果最棒的,手痒遂实现之。 4 | 5 | ![如图](https://github.com/tianjifou/AVPlayer/blob/master/avplayerGift.gif?raw=true) 6 | 7 | **主要原理是滑动距离与分段选择栏的内容成线性关系,再利用上下两层相同内容,不同颜色的UIView。进行移动,可实现,具体算法原理请看代码。** 8 | 9 | **如帮到你,请点赞,谢谢!** -------------------------------------------------------------------------------- /avplayerGift.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tianjifou/AVPlayer/e44b584511d9d4b05b2765642cc5a1c8515ca7a6/avplayerGift.gif --------------------------------------------------------------------------------