├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Demo ├── Demo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Demo.xcscheme ├── Demo.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Demo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── TikTok │ │ │ ├── Contents.json │ │ │ ├── Plist │ │ │ ├── Contents.json │ │ │ └── PhoneCountryCode.dataset │ │ │ │ ├── Contents.json │ │ │ │ └── PhoneCountryCode.plist │ │ │ ├── tiktok_arrow_down.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_arrow_down@2x.png │ │ │ └── tiktok_arrow_down@3x.png │ │ │ ├── tiktok_back.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_back@2x.png │ │ │ └── tiktok_back@3x.png │ │ │ ├── tiktok_close.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_close@2x.png │ │ │ └── tiktok_close@3x.png │ │ │ ├── tiktok_icon_qq.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_icon_qq@2x.png │ │ │ └── tiktok_icon_qq@3x.png │ │ │ ├── tiktok_icon_sina.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_icon_sina@2x.png │ │ │ └── tiktok_icon_sina@3x.png │ │ │ ├── tiktok_icon_toutiao.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_icon_toutiao@2x.png │ │ │ └── tiktok_icon_toutiao@3x.png │ │ │ ├── tiktok_icon_wechat.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_icon_wechat@2x.png │ │ │ └── tiktok_icon_wechat@3x.png │ │ │ ├── tiktok_sign_done.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_sign_done@2x.png │ │ │ └── tiktok_sign_done@3x.png │ │ │ ├── tiktok_sign_loading.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_sign_loading@2x.png │ │ │ └── tiktok_sign_loading@3x.png │ │ │ └── tiktok_textfield_clear.imageset │ │ │ ├── Contents.json │ │ │ ├── tiktok_textfield_clear@2x.png │ │ │ └── tiktok_textfield_clear@3x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── NavigationController.swift │ ├── TikTok │ │ ├── Controller │ │ │ ├── TikTokPasswordLoginViewController.swift │ │ │ └── TikTokPhoneLoginViewController.swift │ │ └── Storyboard │ │ │ └── TikTok.storyboard │ ├── Utils │ │ ├── StoryBoard.swift │ │ └── Then.swift │ └── ViewController.swift ├── Podfile ├── Podfile.lock └── Pods │ ├── Local Podspecs │ ├── AutoInch.podspec.json │ └── UIAdapter.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ └── project.pbxproj │ └── Target Support Files │ ├── Pods-Demo │ ├── Pods-Demo-Info.plist │ ├── Pods-Demo-acknowledgements.markdown │ ├── Pods-Demo-acknowledgements.plist │ ├── Pods-Demo-dummy.m │ ├── Pods-Demo-frameworks-Debug-input-files.xcfilelist │ ├── Pods-Demo-frameworks-Debug-output-files.xcfilelist │ ├── Pods-Demo-frameworks-Release-input-files.xcfilelist │ ├── Pods-Demo-frameworks-Release-output-files.xcfilelist │ ├── Pods-Demo-frameworks.sh │ ├── Pods-Demo-umbrella.h │ ├── Pods-Demo.debug.xcconfig │ ├── Pods-Demo.modulemap │ └── Pods-Demo.release.xcconfig │ └── UIAdapter │ ├── ResourceBundle-Privacy-UIAdapter-Info.plist │ ├── ResourceBundle-UIAdapter-UIAdapter-Info.plist │ ├── UIAdapter-Info.plist │ ├── UIAdapter-dummy.m │ ├── UIAdapter-prefix.pch │ ├── UIAdapter-umbrella.h │ ├── UIAdapter.debug.xcconfig │ ├── UIAdapter.modulemap │ └── UIAdapter.release.xcconfig ├── LICENSE ├── Package.swift ├── README.md ├── README_CN.md ├── Resources ├── Storyboard Constraint.png ├── Storyboard Label Font.png ├── Storyboard TikTok Demo1.jpg └── Storyboard TikTok Demo2.jpg ├── Sources ├── PrivacyInfo.xcprivacy ├── Screen │ └── UIAdapter.Screen.swift ├── UIAdapter.h └── Zoom │ └── UIAdapter.Zoom.swift ├── Tests └── UIAdapterTests │ └── UIAdapterTests.swift ├── UIAdapter.podspec └── UIAdapter.xcodeproj ├── project.pbxproj ├── project.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist └── xcshareddata └── xcschemes └── UIAdapter.xcscheme /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1A42CE6B7492C776E2061D67 /* Pods_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB80693A24BF052917BA4B1F /* Pods_Demo.framework */; }; 11 | C91AE68D219199D4005A8286 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C91AE68C219199D4005A8286 /* NavigationController.swift */; }; 12 | C9E8AED1218DADD600332D5C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8AED0218DADD600332D5C /* AppDelegate.swift */; }; 13 | C9E8AED3218DADD600332D5C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8AED2218DADD600332D5C /* ViewController.swift */; }; 14 | C9E8AED6218DADD600332D5C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9E8AED4218DADD600332D5C /* Main.storyboard */; }; 15 | C9E8AED8218DADD800332D5C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C9E8AED7218DADD800332D5C /* Assets.xcassets */; }; 16 | C9E8AEDB218DADD800332D5C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9E8AED9218DADD800332D5C /* LaunchScreen.storyboard */; }; 17 | C9E8AEEB2190002E00332D5C /* TikTok.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9E8AEEA2190002E00332D5C /* TikTok.storyboard */; }; 18 | C9E8AEED2190018100332D5C /* TikTokPhoneLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8AEEC2190018100332D5C /* TikTokPhoneLoginViewController.swift */; }; 19 | C9E8AEF0219001E000332D5C /* StoryBoard.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8AEEF219001E000332D5C /* StoryBoard.swift */; }; 20 | C9E8AEF2219019BE00332D5C /* TikTokPasswordLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8AEF1219019BE00332D5C /* TikTokPasswordLoginViewController.swift */; }; 21 | C9E8AEF42190339400332D5C /* Then.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8AEF32190339400332D5C /* Then.swift */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 31F26B46261634762DCA08EF /* Pods-Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo.debug.xcconfig"; path = "Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig"; sourceTree = ""; }; 26 | 6D2A1C9D8BBE4301AC51FA2A /* Pods-Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo.release.xcconfig"; path = "Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig"; sourceTree = ""; }; 27 | C91AE68C219199D4005A8286 /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = ""; }; 28 | C9E8AECD218DADD600332D5C /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | C9E8AED0218DADD600332D5C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 30 | C9E8AED2218DADD600332D5C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 31 | C9E8AED5218DADD600332D5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 32 | C9E8AED7218DADD800332D5C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 33 | C9E8AEDA218DADD800332D5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 34 | C9E8AEDC218DADD800332D5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | C9E8AEEA2190002E00332D5C /* TikTok.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TikTok.storyboard; sourceTree = ""; }; 36 | C9E8AEEC2190018100332D5C /* TikTokPhoneLoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TikTokPhoneLoginViewController.swift; sourceTree = ""; }; 37 | C9E8AEEF219001E000332D5C /* StoryBoard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryBoard.swift; sourceTree = ""; }; 38 | C9E8AEF1219019BE00332D5C /* TikTokPasswordLoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TikTokPasswordLoginViewController.swift; sourceTree = ""; }; 39 | C9E8AEF32190339400332D5C /* Then.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Then.swift; sourceTree = ""; }; 40 | DB80693A24BF052917BA4B1F /* Pods_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | C9E8AECA218DADD600332D5C /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 1A42CE6B7492C776E2061D67 /* Pods_Demo.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 3B067D1BB2517F78165BF166 /* Frameworks */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | DB80693A24BF052917BA4B1F /* Pods_Demo.framework */, 59 | ); 60 | name = Frameworks; 61 | sourceTree = ""; 62 | }; 63 | 8B9B50CAF0A18BE579ED7053 /* Pods */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 31F26B46261634762DCA08EF /* Pods-Demo.debug.xcconfig */, 67 | 6D2A1C9D8BBE4301AC51FA2A /* Pods-Demo.release.xcconfig */, 68 | ); 69 | path = Pods; 70 | sourceTree = ""; 71 | }; 72 | C9E8AEC4218DADD600332D5C = { 73 | isa = PBXGroup; 74 | children = ( 75 | C9E8AECF218DADD600332D5C /* Demo */, 76 | C9E8AECE218DADD600332D5C /* Products */, 77 | 8B9B50CAF0A18BE579ED7053 /* Pods */, 78 | 3B067D1BB2517F78165BF166 /* Frameworks */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | C9E8AECE218DADD600332D5C /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | C9E8AECD218DADD600332D5C /* Demo.app */, 86 | ); 87 | name = Products; 88 | sourceTree = ""; 89 | }; 90 | C9E8AECF218DADD600332D5C /* Demo */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | C9E8AEEE219001B700332D5C /* Utils */, 94 | C9E8AEE7218FFFD800332D5C /* TikTok */, 95 | C9E8AED0218DADD600332D5C /* AppDelegate.swift */, 96 | C9E8AED2218DADD600332D5C /* ViewController.swift */, 97 | C91AE68C219199D4005A8286 /* NavigationController.swift */, 98 | C9E8AED4218DADD600332D5C /* Main.storyboard */, 99 | C9E8AED7218DADD800332D5C /* Assets.xcassets */, 100 | C9E8AED9218DADD800332D5C /* LaunchScreen.storyboard */, 101 | C9E8AEDC218DADD800332D5C /* Info.plist */, 102 | ); 103 | path = Demo; 104 | sourceTree = ""; 105 | }; 106 | C9E8AEE7218FFFD800332D5C /* TikTok */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | C9E8AEE92190001300332D5C /* Controller */, 110 | C9E8AEE82190000700332D5C /* Storyboard */, 111 | ); 112 | path = TikTok; 113 | sourceTree = ""; 114 | }; 115 | C9E8AEE82190000700332D5C /* Storyboard */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | C9E8AEEA2190002E00332D5C /* TikTok.storyboard */, 119 | ); 120 | path = Storyboard; 121 | sourceTree = ""; 122 | }; 123 | C9E8AEE92190001300332D5C /* Controller */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | C9E8AEEC2190018100332D5C /* TikTokPhoneLoginViewController.swift */, 127 | C9E8AEF1219019BE00332D5C /* TikTokPasswordLoginViewController.swift */, 128 | ); 129 | path = Controller; 130 | sourceTree = ""; 131 | }; 132 | C9E8AEEE219001B700332D5C /* Utils */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | C9E8AEF32190339400332D5C /* Then.swift */, 136 | C9E8AEEF219001E000332D5C /* StoryBoard.swift */, 137 | ); 138 | path = Utils; 139 | sourceTree = ""; 140 | }; 141 | /* End PBXGroup section */ 142 | 143 | /* Begin PBXNativeTarget section */ 144 | C9E8AECC218DADD600332D5C /* Demo */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = C9E8AEDF218DADD800332D5C /* Build configuration list for PBXNativeTarget "Demo" */; 147 | buildPhases = ( 148 | 27871A0AD279A48DC5780669 /* [CP] Check Pods Manifest.lock */, 149 | C9E8AEC9218DADD600332D5C /* Sources */, 150 | C9E8AECA218DADD600332D5C /* Frameworks */, 151 | C9E8AECB218DADD600332D5C /* Resources */, 152 | 34787AEFE0EEB1280DD997E3 /* [CP] Embed Pods Frameworks */, 153 | ); 154 | buildRules = ( 155 | ); 156 | dependencies = ( 157 | ); 158 | name = Demo; 159 | productName = AutoInchDemo; 160 | productReference = C9E8AECD218DADD600332D5C /* Demo.app */; 161 | productType = "com.apple.product-type.application"; 162 | }; 163 | /* End PBXNativeTarget section */ 164 | 165 | /* Begin PBXProject section */ 166 | C9E8AEC5218DADD600332D5C /* Project object */ = { 167 | isa = PBXProject; 168 | attributes = { 169 | LastSwiftUpdateCheck = 1010; 170 | LastUpgradeCheck = 1010; 171 | ORGANIZATIONNAME = swift; 172 | TargetAttributes = { 173 | C9E8AECC218DADD600332D5C = { 174 | CreatedOnToolsVersion = 10.1; 175 | LastSwiftMigration = 1020; 176 | }; 177 | }; 178 | }; 179 | buildConfigurationList = C9E8AEC8218DADD600332D5C /* Build configuration list for PBXProject "Demo" */; 180 | compatibilityVersion = "Xcode 11.0"; 181 | developmentRegion = en; 182 | hasScannedForEncodings = 0; 183 | knownRegions = ( 184 | en, 185 | Base, 186 | ); 187 | mainGroup = C9E8AEC4218DADD600332D5C; 188 | productRefGroup = C9E8AECE218DADD600332D5C /* Products */; 189 | projectDirPath = ""; 190 | projectRoot = ""; 191 | targets = ( 192 | C9E8AECC218DADD600332D5C /* Demo */, 193 | ); 194 | }; 195 | /* End PBXProject section */ 196 | 197 | /* Begin PBXResourcesBuildPhase section */ 198 | C9E8AECB218DADD600332D5C /* Resources */ = { 199 | isa = PBXResourcesBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | C9E8AEDB218DADD800332D5C /* LaunchScreen.storyboard in Resources */, 203 | C9E8AED8218DADD800332D5C /* Assets.xcassets in Resources */, 204 | C9E8AED6218DADD600332D5C /* Main.storyboard in Resources */, 205 | C9E8AEEB2190002E00332D5C /* TikTok.storyboard in Resources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXResourcesBuildPhase section */ 210 | 211 | /* Begin PBXShellScriptBuildPhase section */ 212 | 27871A0AD279A48DC5780669 /* [CP] Check Pods Manifest.lock */ = { 213 | isa = PBXShellScriptBuildPhase; 214 | buildActionMask = 2147483647; 215 | files = ( 216 | ); 217 | inputFileListPaths = ( 218 | ); 219 | inputPaths = ( 220 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 221 | "${PODS_ROOT}/Manifest.lock", 222 | ); 223 | name = "[CP] Check Pods Manifest.lock"; 224 | outputFileListPaths = ( 225 | ); 226 | outputPaths = ( 227 | "$(DERIVED_FILE_DIR)/Pods-Demo-checkManifestLockResult.txt", 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | shellPath = /bin/sh; 231 | 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"; 232 | showEnvVarsInLog = 0; 233 | }; 234 | 34787AEFE0EEB1280DD997E3 /* [CP] Embed Pods Frameworks */ = { 235 | isa = PBXShellScriptBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | ); 239 | inputFileListPaths = ( 240 | "${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks-${CONFIGURATION}-input-files.xcfilelist", 241 | ); 242 | name = "[CP] Embed Pods Frameworks"; 243 | outputFileListPaths = ( 244 | "${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks-${CONFIGURATION}-output-files.xcfilelist", 245 | ); 246 | runOnlyForDeploymentPostprocessing = 0; 247 | shellPath = /bin/sh; 248 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh\"\n"; 249 | showEnvVarsInLog = 0; 250 | }; 251 | /* End PBXShellScriptBuildPhase section */ 252 | 253 | /* Begin PBXSourcesBuildPhase section */ 254 | C9E8AEC9218DADD600332D5C /* Sources */ = { 255 | isa = PBXSourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | C9E8AED3218DADD600332D5C /* ViewController.swift in Sources */, 259 | C9E8AED1218DADD600332D5C /* AppDelegate.swift in Sources */, 260 | C9E8AEF2219019BE00332D5C /* TikTokPasswordLoginViewController.swift in Sources */, 261 | C9E8AEED2190018100332D5C /* TikTokPhoneLoginViewController.swift in Sources */, 262 | C91AE68D219199D4005A8286 /* NavigationController.swift in Sources */, 263 | C9E8AEF42190339400332D5C /* Then.swift in Sources */, 264 | C9E8AEF0219001E000332D5C /* StoryBoard.swift in Sources */, 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | }; 268 | /* End PBXSourcesBuildPhase section */ 269 | 270 | /* Begin PBXVariantGroup section */ 271 | C9E8AED4218DADD600332D5C /* Main.storyboard */ = { 272 | isa = PBXVariantGroup; 273 | children = ( 274 | C9E8AED5218DADD600332D5C /* Base */, 275 | ); 276 | name = Main.storyboard; 277 | sourceTree = ""; 278 | }; 279 | C9E8AED9218DADD800332D5C /* LaunchScreen.storyboard */ = { 280 | isa = PBXVariantGroup; 281 | children = ( 282 | C9E8AEDA218DADD800332D5C /* Base */, 283 | ); 284 | name = LaunchScreen.storyboard; 285 | sourceTree = ""; 286 | }; 287 | /* End PBXVariantGroup section */ 288 | 289 | /* Begin XCBuildConfiguration section */ 290 | C9E8AEDD218DADD800332D5C /* Debug */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | ALWAYS_SEARCH_USER_PATHS = NO; 294 | CLANG_ANALYZER_NONNULL = YES; 295 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 296 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 297 | CLANG_CXX_LIBRARY = "libc++"; 298 | CLANG_ENABLE_MODULES = YES; 299 | CLANG_ENABLE_OBJC_ARC = YES; 300 | CLANG_ENABLE_OBJC_WEAK = YES; 301 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 302 | CLANG_WARN_BOOL_CONVERSION = YES; 303 | CLANG_WARN_COMMA = YES; 304 | CLANG_WARN_CONSTANT_CONVERSION = YES; 305 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 306 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 307 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 308 | CLANG_WARN_EMPTY_BODY = YES; 309 | CLANG_WARN_ENUM_CONVERSION = YES; 310 | CLANG_WARN_INFINITE_RECURSION = YES; 311 | CLANG_WARN_INT_CONVERSION = YES; 312 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 313 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 314 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 315 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 316 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 317 | CLANG_WARN_STRICT_PROTOTYPES = YES; 318 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 319 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 320 | CLANG_WARN_UNREACHABLE_CODE = YES; 321 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 322 | CODE_SIGN_IDENTITY = "iPhone Developer"; 323 | COPY_PHASE_STRIP = NO; 324 | DEBUG_INFORMATION_FORMAT = dwarf; 325 | ENABLE_STRICT_OBJC_MSGSEND = YES; 326 | ENABLE_TESTABILITY = YES; 327 | GCC_C_LANGUAGE_STANDARD = gnu11; 328 | GCC_DYNAMIC_NO_PIC = NO; 329 | GCC_NO_COMMON_BLOCKS = YES; 330 | GCC_OPTIMIZATION_LEVEL = 0; 331 | GCC_PREPROCESSOR_DEFINITIONS = ( 332 | "DEBUG=1", 333 | "$(inherited)", 334 | ); 335 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 336 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 337 | GCC_WARN_UNDECLARED_SELECTOR = YES; 338 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 339 | GCC_WARN_UNUSED_FUNCTION = YES; 340 | GCC_WARN_UNUSED_VARIABLE = YES; 341 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 342 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 343 | MTL_FAST_MATH = YES; 344 | ONLY_ACTIVE_ARCH = YES; 345 | SDKROOT = iphoneos; 346 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 347 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 348 | }; 349 | name = Debug; 350 | }; 351 | C9E8AEDE218DADD800332D5C /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ALWAYS_SEARCH_USER_PATHS = NO; 355 | CLANG_ANALYZER_NONNULL = YES; 356 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 357 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 358 | CLANG_CXX_LIBRARY = "libc++"; 359 | CLANG_ENABLE_MODULES = YES; 360 | CLANG_ENABLE_OBJC_ARC = YES; 361 | CLANG_ENABLE_OBJC_WEAK = YES; 362 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 363 | CLANG_WARN_BOOL_CONVERSION = YES; 364 | CLANG_WARN_COMMA = YES; 365 | CLANG_WARN_CONSTANT_CONVERSION = YES; 366 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 367 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 368 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 369 | CLANG_WARN_EMPTY_BODY = YES; 370 | CLANG_WARN_ENUM_CONVERSION = YES; 371 | CLANG_WARN_INFINITE_RECURSION = YES; 372 | CLANG_WARN_INT_CONVERSION = YES; 373 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 374 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 375 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 376 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 377 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 378 | CLANG_WARN_STRICT_PROTOTYPES = YES; 379 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 380 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 381 | CLANG_WARN_UNREACHABLE_CODE = YES; 382 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 383 | CODE_SIGN_IDENTITY = "iPhone Developer"; 384 | COPY_PHASE_STRIP = NO; 385 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 386 | ENABLE_NS_ASSERTIONS = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu11; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 397 | MTL_ENABLE_DEBUG_INFO = NO; 398 | MTL_FAST_MATH = YES; 399 | SDKROOT = iphoneos; 400 | SWIFT_COMPILATION_MODE = wholemodule; 401 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 402 | VALIDATE_PRODUCT = YES; 403 | }; 404 | name = Release; 405 | }; 406 | C9E8AEE0218DADD800332D5C /* Debug */ = { 407 | isa = XCBuildConfiguration; 408 | baseConfigurationReference = 31F26B46261634762DCA08EF /* Pods-Demo.debug.xcconfig */; 409 | buildSettings = { 410 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 411 | CODE_SIGN_STYLE = Automatic; 412 | DEVELOPMENT_TEAM = 8G74YECJ4Z; 413 | INFOPLIST_FILE = Demo/Info.plist; 414 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 415 | LD_RUNPATH_SEARCH_PATHS = ( 416 | "$(inherited)", 417 | "@executable_path/Frameworks", 418 | ); 419 | PRODUCT_BUNDLE_IDENTIFIER = com.lee.uiadapter.demo; 420 | PRODUCT_NAME = "$(TARGET_NAME)"; 421 | SWIFT_VERSION = 5.0; 422 | TARGETED_DEVICE_FAMILY = "1,2"; 423 | }; 424 | name = Debug; 425 | }; 426 | C9E8AEE1218DADD800332D5C /* Release */ = { 427 | isa = XCBuildConfiguration; 428 | baseConfigurationReference = 6D2A1C9D8BBE4301AC51FA2A /* Pods-Demo.release.xcconfig */; 429 | buildSettings = { 430 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 431 | CODE_SIGN_STYLE = Automatic; 432 | DEVELOPMENT_TEAM = 8G74YECJ4Z; 433 | INFOPLIST_FILE = Demo/Info.plist; 434 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 435 | LD_RUNPATH_SEARCH_PATHS = ( 436 | "$(inherited)", 437 | "@executable_path/Frameworks", 438 | ); 439 | PRODUCT_BUNDLE_IDENTIFIER = com.lee.uiadapter.demo; 440 | PRODUCT_NAME = "$(TARGET_NAME)"; 441 | SWIFT_VERSION = 5.0; 442 | TARGETED_DEVICE_FAMILY = "1,2"; 443 | }; 444 | name = Release; 445 | }; 446 | /* End XCBuildConfiguration section */ 447 | 448 | /* Begin XCConfigurationList section */ 449 | C9E8AEC8218DADD600332D5C /* Build configuration list for PBXProject "Demo" */ = { 450 | isa = XCConfigurationList; 451 | buildConfigurations = ( 452 | C9E8AEDD218DADD800332D5C /* Debug */, 453 | C9E8AEDE218DADD800332D5C /* Release */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | C9E8AEDF218DADD800332D5C /* Build configuration list for PBXNativeTarget "Demo" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | C9E8AEE0218DADD800332D5C /* Debug */, 462 | C9E8AEE1218DADD800332D5C /* Release */, 463 | ); 464 | defaultConfigurationIsVisible = 0; 465 | defaultConfigurationName = Release; 466 | }; 467 | /* End XCConfigurationList section */ 468 | }; 469 | rootObject = C9E8AEC5218DADD600332D5C /* Project object */; 470 | } 471 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Demo/Demo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Demo/Demo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by 李响 on 2018/11/3. 6 | // Copyright © 2018 swift. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import UIAdapter 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | /* 19 | // 默认计算逻辑以375屏幕宽度为基准进行等比例计算 20 | // 如果需要可以重新设置自定义的计算逻辑 21 | UIAdapter.Zoom.set { (value) -> Double in 22 | // .... calculation .. 23 | return value 24 | } 25 | */ 26 | 27 | return true 28 | } 29 | 30 | func applicationWillResignActive(_ application: UIApplication) { 31 | // 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. 32 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 33 | } 34 | 35 | func applicationDidEnterBackground(_ application: UIApplication) { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | func applicationWillEnterForeground(_ application: UIApplication) { 41 | // 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. 42 | } 43 | 44 | func applicationDidBecomeActive(_ application: UIApplication) { 45 | // 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. 46 | } 47 | 48 | func applicationWillTerminate(_ application: UIApplication) { 49 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 50 | } 51 | 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Demo/Demo/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 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/Plist/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/Plist/PhoneCountryCode.dataset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "data" : [ 7 | { 8 | "idiom" : "universal", 9 | "filename" : "PhoneCountryCode.plist" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/Plist/PhoneCountryCode.dataset/PhoneCountryCode.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/Plist/PhoneCountryCode.dataset/PhoneCountryCode.plist -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_arrow_down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_arrow_down@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_arrow_down@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_arrow_down.imageset/tiktok_arrow_down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_arrow_down.imageset/tiktok_arrow_down@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_arrow_down.imageset/tiktok_arrow_down@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_arrow_down.imageset/tiktok_arrow_down@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_back@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_back@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_back.imageset/tiktok_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_back.imageset/tiktok_back@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_back.imageset/tiktok_back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_back.imageset/tiktok_back@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_close@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_close@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_close.imageset/tiktok_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_close.imageset/tiktok_close@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_close.imageset/tiktok_close@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_close.imageset/tiktok_close@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_qq.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_icon_qq@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_icon_qq@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_qq.imageset/tiktok_icon_qq@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_qq.imageset/tiktok_icon_qq@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_qq.imageset/tiktok_icon_qq@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_qq.imageset/tiktok_icon_qq@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_sina.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_icon_sina@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_icon_sina@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_sina.imageset/tiktok_icon_sina@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_sina.imageset/tiktok_icon_sina@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_sina.imageset/tiktok_icon_sina@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_sina.imageset/tiktok_icon_sina@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_toutiao.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_icon_toutiao@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_icon_toutiao@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_toutiao.imageset/tiktok_icon_toutiao@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_toutiao.imageset/tiktok_icon_toutiao@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_toutiao.imageset/tiktok_icon_toutiao@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_toutiao.imageset/tiktok_icon_toutiao@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_wechat.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_icon_wechat@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_icon_wechat@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_wechat.imageset/tiktok_icon_wechat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_wechat.imageset/tiktok_icon_wechat@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_wechat.imageset/tiktok_icon_wechat@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_icon_wechat.imageset/tiktok_icon_wechat@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_done.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_sign_done@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_sign_done@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_done.imageset/tiktok_sign_done@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_done.imageset/tiktok_sign_done@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_done.imageset/tiktok_sign_done@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_done.imageset/tiktok_sign_done@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_loading.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_sign_loading@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_sign_loading@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_loading.imageset/tiktok_sign_loading@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_loading.imageset/tiktok_sign_loading@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_loading.imageset/tiktok_sign_loading@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_sign_loading.imageset/tiktok_sign_loading@3x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_textfield_clear.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tiktok_textfield_clear@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tiktok_textfield_clear@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_textfield_clear.imageset/tiktok_textfield_clear@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_textfield_clear.imageset/tiktok_textfield_clear@2x.png -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/TikTok/tiktok_textfield_clear.imageset/tiktok_textfield_clear@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Demo/Demo/Assets.xcassets/TikTok/tiktok_textfield_clear.imageset/tiktok_textfield_clear@3x.png -------------------------------------------------------------------------------- /Demo/Demo/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 | 27 | 28 | -------------------------------------------------------------------------------- /Demo/Demo/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 | 26 | 27 | 28 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /Demo/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | UIAdapter 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UIUserInterfaceStyle 47 | Light 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Demo/Demo/NavigationController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationController.swift 3 | // Demo 4 | // 5 | // Created by 李响 on 2018/11/6. 6 | // Copyright © 2018 swift. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class NavigationController: UINavigationController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | interactivePopGestureRecognizer?.delegate = self 17 | } 18 | 19 | override func viewWillAppear(_ animated: Bool) { 20 | super.viewWillAppear(animated) 21 | view.frame = UIScreen.main.bounds 22 | } 23 | 24 | override func pushViewController(_ viewController: UIViewController, animated: Bool) { 25 | interactivePopGestureRecognizer?.isEnabled = false 26 | super.pushViewController(viewController, animated: animated) 27 | interactivePopGestureRecognizer?.isEnabled = true 28 | } 29 | 30 | override var childForStatusBarStyle: UIViewController? { 31 | return topViewController 32 | } 33 | 34 | override var shouldAutorotate: Bool { 35 | return topViewController?.shouldAutorotate ?? false 36 | } 37 | 38 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 39 | return topViewController?.supportedInterfaceOrientations ?? .portrait 40 | } 41 | 42 | override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { 43 | return topViewController?.preferredInterfaceOrientationForPresentation ?? .portrait 44 | } 45 | } 46 | 47 | extension NavigationController: UIGestureRecognizerDelegate { 48 | 49 | func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 50 | return viewControllers.count > 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Demo/Demo/TikTok/Controller/TikTokPasswordLoginViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TikTokPasswordLoginViewController.swift 3 | // Demo 4 | // 5 | // Created by 李响 on 2018/11/5. 6 | // Copyright © 2018 swift. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TikTokPasswordLoginViewController: UIViewController { 12 | 13 | var phone = "" 14 | 15 | private lazy var layer = CAGradientLayer().then { 16 | let colors: [CGColor] = [#colorLiteral(red: 0.4727493525, green: 0.4444301128, blue: 0.9979013801, alpha: 1), #colorLiteral(red: 0.5695798397, green: 0.2927905917, blue: 0.9881889224, alpha: 1), #colorLiteral(red: 0.6905713677, green: 0.1041976586, blue: 0.9767265916, alpha: 1), #colorLiteral(red: 0.7510715127, green: 0.002722046804, blue: 0.9681376815, alpha: 1)] 17 | $0.locations = [0.0, 0.4, 0.8, 1.0] 18 | $0.colors = colors 19 | $0.opacity = 1.0 20 | } 21 | 22 | @IBOutlet weak var bottomConstraint: NSLayoutConstraint! 23 | 24 | @IBOutlet weak var phoneTextField: UITextField! 25 | @IBOutlet weak var passwordTextField: UITextField! 26 | @IBOutlet weak var areaButton: UIButton! 27 | @IBOutlet weak var doneButton: UIButton! 28 | 29 | private var isLogging = false 30 | private var isDidAppear = false 31 | 32 | override func viewDidLoad() { 33 | super.viewDidLoad() 34 | 35 | setup() 36 | setupNotification() 37 | } 38 | 39 | override func willMove(toParent parent: UIViewController?) { 40 | super.willMove(toParent: parent) 41 | 42 | isDidAppear = false 43 | } 44 | 45 | override func viewDidAppear(_ animated: Bool) { 46 | super.viewDidAppear(animated) 47 | 48 | isDidAppear = true 49 | navigationController?.interactivePopGestureRecognizer?.isEnabled = true 50 | 51 | if phone.count < 13 { 52 | phoneTextField.becomeFirstResponder() 53 | } else { 54 | passwordTextField.becomeFirstResponder() 55 | } 56 | } 57 | 58 | override func viewDidLayoutSubviews() { 59 | super.viewDidLayoutSubviews() 60 | 61 | layer.frame = view.bounds 62 | } 63 | 64 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 65 | super.touchesBegan(touches, with: event) 66 | guard !isLogging else { 67 | return 68 | } 69 | 70 | view.endEditing(true) 71 | } 72 | 73 | override var preferredStatusBarStyle: UIStatusBarStyle { 74 | return .lightContent 75 | } 76 | 77 | override var shouldAutorotate: Bool { 78 | return false 79 | } 80 | 81 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 82 | return .portrait 83 | } 84 | 85 | override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { 86 | return .portrait 87 | } 88 | 89 | @IBAction func areaAction(_ sender: UIButton) { 90 | 91 | } 92 | 93 | @IBAction func doneAction(_ sender: UIButton) { 94 | guard 95 | let phone = phoneTextField.text, 96 | let password = passwordTextField.text else { 97 | return 98 | } 99 | guard sender.alpha == 1 else { 100 | return 101 | } 102 | guard !isLogging else { 103 | return 104 | } 105 | 106 | sender.setBackgroundImage(#imageLiteral(resourceName: "tiktok_sign_loading"), for: .normal) 107 | 108 | let animation = CABasicAnimation() 109 | animation.keyPath = "transform.rotation.z" 110 | animation.fromValue = 0 111 | animation.toValue = 360 * CGFloat(CGFloat.pi / 180) 112 | animation.duration = 0.9 113 | animation.repeatCount = HUGE 114 | animation.isRemovedOnCompletion = false 115 | sender.layer.add(animation, forKey: "loading") 116 | 117 | logging(phone.trimmingCharacters(in: .whitespaces), password) { 118 | [weak self] (result) in 119 | guard let self = self else { return } 120 | 121 | if result { 122 | self.view.endEditing(true) 123 | self.dismiss(animated: true) 124 | 125 | } else { 126 | sender.layer.removeAllAnimations() 127 | sender.setBackgroundImage(#imageLiteral(resourceName: "tiktok_sign_done"), for: .normal) 128 | } 129 | } 130 | } 131 | 132 | @IBAction func phoneChangeAction(_ sender: UITextField) { 133 | guard let text = sender.text else { 134 | return 135 | } 136 | 137 | if text.count > phone.count { 138 | if text.count == 3 || text.count == 8 { 139 | sender.text = text + " " 140 | } 141 | if text.count >= 13 { 142 | sender.text = String(text.prefix(13)) 143 | passwordTextField.becomeFirstResponder() 144 | } 145 | 146 | phone = text 147 | 148 | } else if text.count < phone.count { 149 | if text.count == 3 || text.count == 8 { 150 | sender.text = String(text.prefix(text.count - 1)) 151 | } 152 | 153 | phone = text 154 | } 155 | 156 | checkDoneStatus() 157 | } 158 | 159 | @IBAction func passwordChangeAction(_ sender: UITextField) { 160 | guard let text = sender.text else { 161 | return 162 | } 163 | 164 | if text.count >= 6 { 165 | sender.text = String(text.prefix(6)) 166 | } 167 | 168 | checkDoneStatus() 169 | } 170 | } 171 | 172 | extension TikTokPasswordLoginViewController { 173 | 174 | private func setup() { 175 | navigationController?.interactivePopGestureRecognizer?.isEnabled = false 176 | 177 | view.layer.insertSublayer(layer, at: 0) 178 | view.layoutIfNeeded() 179 | 180 | phoneTextField.text = phone 181 | 182 | if let button = phoneTextField.value(forKey: "_clearButton") as? UIButton { 183 | button.setImage(#imageLiteral(resourceName: "tiktok_textfield_clear"), for: .normal) 184 | button.adjustsImageWhenHighlighted = false 185 | } 186 | if let button = passwordTextField.value(forKey: "_clearButton") as? UIButton { 187 | button.setImage(#imageLiteral(resourceName: "tiktok_textfield_clear"), for: .normal) 188 | button.adjustsImageWhenHighlighted = false 189 | } 190 | 191 | phoneTextField.attributedPlaceholder = .init( 192 | string: phoneTextField.placeholder ?? "", 193 | attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.5)] 194 | ) 195 | passwordTextField.attributedPlaceholder = .init( 196 | string: passwordTextField.placeholder ?? "", 197 | attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.5)] 198 | ) 199 | } 200 | 201 | private func setupNotification() { 202 | NotificationCenter.default.addObserver( 203 | self, 204 | selector: #selector(keyboardWillChangeFrame), 205 | name: UIResponder.keyboardWillChangeFrameNotification, 206 | object: nil 207 | ) 208 | } 209 | 210 | private func checkDoneStatus() { 211 | guard 212 | let phone = phoneTextField.text, 213 | let password = passwordTextField.text else { 214 | return 215 | } 216 | 217 | let ok = phone.count == 13 && !password.isEmpty 218 | UIView.beginAnimations("", context: nil) 219 | UIView.setAnimationDuration(0.25) 220 | doneButton.alpha = ok ? 1.0 : 0.5 221 | UIView.commitAnimations() 222 | } 223 | } 224 | 225 | extension TikTokPasswordLoginViewController { 226 | 227 | private func logging(_ phone: String, 228 | _ password: String, 229 | _ completion: @escaping (Bool) -> Void) { 230 | isLogging = true 231 | // 假装请求登录 232 | DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [weak self] in 233 | self?.isLogging = false 234 | // 随机返回成功 or 失败 235 | let result = Int.random(in: 0...1) == 0 ? true : false 236 | completion(result) 237 | } 238 | } 239 | } 240 | 241 | extension TikTokPasswordLoginViewController { 242 | 243 | @objc private func keyboardWillChangeFrame(_ sender: Notification) { 244 | guard let info = sender.userInfo else { 245 | return 246 | } 247 | guard let local = info[UIResponder.keyboardIsLocalUserInfoKey] as? Int, local == 1 else { 248 | return 249 | } 250 | guard 251 | let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, 252 | let curveRaw = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int, 253 | let curve = UIView.AnimationCurve(rawValue: curveRaw), 254 | let end = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { 255 | return 256 | } 257 | guard isDidAppear else { 258 | return 259 | } 260 | 261 | bottomConstraint.constant = view.bounds.height - end.minY 262 | 263 | UIView.beginAnimations("keyboard", context: nil) 264 | UIView.setAnimationDuration(duration) 265 | UIView.setAnimationCurve(curve) 266 | view.layoutIfNeeded() 267 | UIView.commitAnimations() 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /Demo/Demo/TikTok/Controller/TikTokPhoneLoginViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TikTokPhoneLoginViewController.swift 3 | // Demo 4 | // 5 | // Created by 李响 on 2018/11/5. 6 | // Copyright © 2018 swift. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TikTokPhoneLoginViewController: UIViewController { 12 | 13 | private lazy var layer = CAGradientLayer().then { 14 | let colors: [CGColor] = [#colorLiteral(red: 0.4727493525, green: 0.4444301128, blue: 0.9979013801, alpha: 1), #colorLiteral(red: 0.5695798397, green: 0.2927905917, blue: 0.9881889224, alpha: 1), #colorLiteral(red: 0.6905713677, green: 0.1041976586, blue: 0.9767265916, alpha: 1), #colorLiteral(red: 0.7510715127, green: 0.002722046804, blue: 0.9681376815, alpha: 1)] 15 | $0.locations = [0.0, 0.4, 0.8, 1.0] 16 | $0.colors = colors 17 | $0.opacity = 0.9 18 | } 19 | 20 | @IBOutlet weak var bottomConstraint: NSLayoutConstraint! 21 | 22 | @IBOutlet weak var phoneTextField: UITextField! 23 | @IBOutlet weak var codeTextField: UITextField! 24 | @IBOutlet weak var areaButton: UIButton! 25 | @IBOutlet weak var captchaButton: UIButton! 26 | @IBOutlet weak var doneButton: UIButton! 27 | @IBOutlet weak var loginView: UIView! 28 | @IBOutlet weak var otherView: UIView! 29 | 30 | private var phone = "" 31 | private var isLogging = false 32 | 33 | override func viewDidLoad() { 34 | super.viewDidLoad() 35 | 36 | setup() 37 | setupNotification() 38 | 39 | phoneTextField.becomeFirstResponder() 40 | } 41 | 42 | override func viewDidAppear(_ animated: Bool) { 43 | super.viewDidAppear(animated) 44 | 45 | if phone.count < 13 { 46 | phoneTextField.becomeFirstResponder() 47 | } else { 48 | codeTextField.becomeFirstResponder() 49 | } 50 | } 51 | 52 | override func viewDidLayoutSubviews() { 53 | super.viewDidLayoutSubviews() 54 | 55 | layer.frame = view.bounds 56 | } 57 | 58 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 59 | switch segue.identifier { 60 | case "password": 61 | guard let controller = segue.destination as? TikTokPasswordLoginViewController else { 62 | return 63 | } 64 | 65 | controller.phone = phone 66 | 67 | default: break 68 | } 69 | } 70 | 71 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 72 | super.touchesBegan(touches, with: event) 73 | guard !isLogging else { 74 | return 75 | } 76 | 77 | view.endEditing(true) 78 | dismiss(animated: true) 79 | } 80 | 81 | override var preferredStatusBarStyle: UIStatusBarStyle { 82 | return .lightContent 83 | } 84 | 85 | override var shouldAutorotate: Bool { 86 | return false 87 | } 88 | 89 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 90 | return .portrait 91 | } 92 | 93 | override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { 94 | return .portrait 95 | } 96 | 97 | @IBAction func areaAction(_ sender: UIButton) { 98 | 99 | } 100 | 101 | @IBAction func captchaAction(_ sender: UIButton) { 102 | 103 | } 104 | 105 | @IBAction func doneAction(_ sender: UIButton) { 106 | guard 107 | let phone = phoneTextField.text, 108 | let code = codeTextField.text else { 109 | return 110 | } 111 | guard sender.alpha == 1 else { 112 | return 113 | } 114 | guard !isLogging else { 115 | return 116 | } 117 | 118 | sender.setBackgroundImage(#imageLiteral(resourceName: "tiktok_sign_loading"), for: .normal) 119 | 120 | let animation = CABasicAnimation() 121 | animation.keyPath = "transform.rotation.z" 122 | animation.fromValue = 0 123 | animation.toValue = 360 * CGFloat(CGFloat.pi / 180) 124 | animation.duration = 0.9 125 | animation.repeatCount = HUGE 126 | animation.isRemovedOnCompletion = false 127 | sender.layer.add(animation, forKey: "loading") 128 | 129 | logging(phone.trimmingCharacters(in: .whitespaces), code) { 130 | [weak self] (result) in 131 | guard let self = self else { return } 132 | 133 | if result { 134 | self.view.endEditing(true) 135 | self.dismiss(animated: true) 136 | 137 | } else { 138 | sender.layer.removeAllAnimations() 139 | sender.setBackgroundImage(#imageLiteral(resourceName: "tiktok_sign_done"), for: .normal) 140 | } 141 | } 142 | } 143 | 144 | @IBAction func phoneChangeAction(_ sender: UITextField) { 145 | guard let text = sender.text else { 146 | return 147 | } 148 | 149 | if text.count > phone.count { 150 | if text.count == 3 || text.count == 8 { 151 | sender.text = text + " " 152 | } 153 | if text.count >= 13 { 154 | sender.text = String(text.prefix(13)) 155 | codeTextField.becomeFirstResponder() 156 | } 157 | 158 | phone = text 159 | 160 | } else if text.count < phone.count { 161 | if text.count == 3 || text.count == 8 { 162 | sender.text = String(text.prefix(text.count - 1)) 163 | } 164 | 165 | phone = text 166 | } 167 | 168 | UIView.beginAnimations("", context: nil) 169 | UIView.setAnimationDuration(0.25) 170 | captchaButton.isEnabled = !text.isEmpty 171 | loginView.alpha = text.isEmpty ? 0 : 1 172 | otherView.alpha = text.isEmpty ? 1 : 0 173 | UIView.commitAnimations() 174 | 175 | checkDoneStatus() 176 | } 177 | 178 | @IBAction func codeChangeAction(_ sender: UITextField) { 179 | guard let text = sender.text else { 180 | return 181 | } 182 | 183 | if text.count >= 6 { 184 | sender.text = String(text.prefix(6)) 185 | } 186 | 187 | checkDoneStatus() 188 | } 189 | } 190 | 191 | extension TikTokPhoneLoginViewController { 192 | 193 | private func setup() { 194 | view.layer.insertSublayer(layer, at: 0) 195 | view.layoutIfNeeded() 196 | 197 | if let button = phoneTextField.value(forKey: "_clearButton") as? UIButton { 198 | button.setImage(#imageLiteral(resourceName: "tiktok_textfield_clear"), for: .normal) 199 | button.adjustsImageWhenHighlighted = false 200 | } 201 | 202 | phoneTextField.attributedPlaceholder = .init( 203 | string: phoneTextField.placeholder ?? "", 204 | attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.5)] 205 | ) 206 | codeTextField.attributedPlaceholder = .init( 207 | string: codeTextField.placeholder ?? "", 208 | attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.5)] 209 | ) 210 | } 211 | 212 | private func setupNotification() { 213 | NotificationCenter.default.addObserver( 214 | self, 215 | selector: #selector(keyboardWillChangeFrame), 216 | name: UIResponder.keyboardWillChangeFrameNotification, 217 | object: nil 218 | ) 219 | } 220 | 221 | private func checkDoneStatus() { 222 | guard 223 | let phone = phoneTextField.text, 224 | let code = codeTextField.text else { 225 | return 226 | } 227 | 228 | let ok = phone.count == 13 && code.count == 6 229 | UIView.beginAnimations("", context: nil) 230 | UIView.setAnimationDuration(0.25) 231 | doneButton.alpha = ok ? 1.0 : 0.5 232 | UIView.commitAnimations() 233 | } 234 | } 235 | 236 | extension TikTokPhoneLoginViewController { 237 | 238 | private func logging(_ phone: String, 239 | _ code: String, 240 | _ completion: @escaping (Bool) -> Void) { 241 | isLogging = true 242 | // 假装请求登录 243 | DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [weak self] in 244 | self?.isLogging = false 245 | // 随机返回成功 or 失败 246 | let result = Int.random(in: 0...1) == 0 ? true : false 247 | completion(result) 248 | } 249 | } 250 | } 251 | 252 | extension TikTokPhoneLoginViewController { 253 | 254 | @objc private func keyboardWillChangeFrame(_ sender: Notification) { 255 | guard let info = sender.userInfo else { 256 | return 257 | } 258 | guard let local = info[UIResponder.keyboardIsLocalUserInfoKey] as? Int, local == 1 else { 259 | return 260 | } 261 | guard 262 | let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, 263 | let curveRaw = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int, 264 | let curve = UIView.AnimationCurve(rawValue: curveRaw), 265 | let end = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { 266 | return 267 | } 268 | 269 | bottomConstraint.constant = view.bounds.height - end.minY 270 | 271 | UIView.beginAnimations("keyboard", context: nil) 272 | UIView.setAnimationDuration(duration) 273 | UIView.setAnimationCurve(curve) 274 | view.layoutIfNeeded() 275 | UIView.commitAnimations() 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /Demo/Demo/Utils/StoryBoard.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StoryBoard.swift 3 | // LiveTrivia 4 | // 5 | // Created by 李响 on 2018/1/16. 6 | // Copyright © 2018年 LiveTrivia. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | enum StoryBoard: String { 13 | case main = "Main" 14 | case tiktok = "TikTok" 15 | 16 | var storyboard: UIStoryboard { 17 | return UIStoryboard(name: rawValue, bundle: nil) 18 | } 19 | 20 | func instance() -> T { 21 | return storyboard.instantiateViewController(withIdentifier: String(describing: T.self)) as! T 22 | } 23 | } 24 | 25 | extension UIViewController { 26 | 27 | @IBAction func backAction() { 28 | view.endEditing(false) 29 | if 30 | let navigation = navigationController, 31 | navigation.viewControllers.first != self { 32 | navigation.popViewController(animated: true) 33 | 34 | } else { 35 | let presenting = presentingViewController ?? self 36 | presenting.dismiss(animated: true) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Demo/Demo/Utils/Then.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Suyeol Jeon (xoul.kr) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Foundation 24 | import CoreGraphics 25 | #if os(iOS) || os(tvOS) 26 | import UIKit.UIGeometry 27 | #endif 28 | 29 | public protocol Then {} 30 | 31 | extension Then where Self: Any { 32 | 33 | /// Makes it available to set properties with closures just after initializing and copying the value types. 34 | /// 35 | /// let frame = CGRect().with { 36 | /// $0.origin.x = 10 37 | /// $0.size.width = 100 38 | /// } 39 | public func with(_ block: (inout Self) throws -> Void) rethrows -> Self { 40 | var copy = self 41 | try block(©) 42 | return copy 43 | } 44 | 45 | /// Makes it available to execute something with closures. 46 | /// 47 | /// UserDefaults.standard.do { 48 | /// $0.set("devxoul", forKey: "username") 49 | /// $0.set("devxoul@gmail.com", forKey: "email") 50 | /// $0.synchronize() 51 | /// } 52 | public func `do`(_ block: (Self) throws -> Void) rethrows { 53 | try block(self) 54 | } 55 | 56 | } 57 | 58 | extension Then where Self: AnyObject { 59 | 60 | /// Makes it available to set properties with closures just after initializing. 61 | /// 62 | /// let label = UILabel().then { 63 | /// $0.textAlignment = .Center 64 | /// $0.textColor = UIColor.blackColor() 65 | /// $0.text = "Hello, World!" 66 | /// } 67 | public func then(_ block: (Self) throws -> Void) rethrows -> Self { 68 | try block(self) 69 | return self 70 | } 71 | 72 | } 73 | 74 | extension NSObject: Then {} 75 | 76 | extension CGPoint: Then {} 77 | extension CGRect: Then {} 78 | extension CGSize: Then {} 79 | extension CGVector: Then {} 80 | 81 | #if os(iOS) || os(tvOS) 82 | extension UIEdgeInsets: Then {} 83 | extension UIOffset: Then {} 84 | extension UIRectEdge: Then {} 85 | #endif 86 | -------------------------------------------------------------------------------- /Demo/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Demo 4 | // 5 | // Created by 李响 on 2018/11/3. 6 | // Copyright © 2018 swift. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import UIAdapter 11 | 12 | class ViewController: UITableViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | // Do any additional setup after loading the view, typically from a nib. 17 | 18 | print("this is " + "default".screen 19 | .width(equalTo: 375, is: "宽度 等于 375") 20 | .width(lessThan: 414, is: "宽度 小于 414") 21 | .width(greaterThan: 414, is: "宽度 大于 414") 22 | .height(equalTo: 700, is: "高度 等于 375") 23 | .height(lessThan: 844, is: "高度 小于 844") 24 | .height(greaterThan: 844, is: "高度 大于 844") 25 | .inch(._4_7, is: "4.7 英寸") 26 | .inch(._5_8, is: "5.8 英寸") 27 | .inch(._6_5, is: "6.5 英寸") 28 | .level(.compact, is: "屏幕级别 紧凑屏 (4:3)") 29 | .level(.regular, is: "屏幕级别 常规屏 (16:9)") 30 | .level(.full, is: "屏幕级别 全面屏 (19.5:9)") 31 | .value 32 | ) 33 | 34 | // Range用法: 默认值0, 当宽度小于等于375 返回1 35 | print(0.screen.width(...375, is: 1).value) 36 | // Range用法: 默认值0, 当宽度为375至414范围时 返回1 37 | print(0.screen.width(375...414, is: 1).value) 38 | // Range用法: 默认值0, 当屏幕小于5.5英寸时 返回1 39 | print(0.screen.inch(..<5.5, is: 1).value) 40 | 41 | // 默认值 0 在3.5英寸的屏幕时返回1, 在4.0英寸的屏幕时返回2 42 | print(0.screen.inch(._3_5, is: 1).inch(._4_0, is: 2).value) 43 | // 默认值 0 在全面屏时返回1, 在6.1英寸的屏幕时返回2 44 | print(0.screen.level(.full, is: 1).inch(._6_1, is: 2).value) 45 | // 默认值 100 在宽度为375级别的屏幕时 正常返回120, 如果为缩放模式则返回110 46 | print(100.screen.width(equalTo: 375, is: 120, zoomed: 110).value) 47 | 48 | print("当前屏幕级别: \(UIAdapter.Screen.main.level)") 49 | print("是否为全面屏: \(UIAdapter.Screen.main.level.isFull)") 50 | print("是否为缩放模式: \(UIAdapter.Screen.main.isZoomedMode)") 51 | } 52 | 53 | override var preferredStatusBarStyle: UIStatusBarStyle { 54 | return .default 55 | } 56 | 57 | override var shouldAutorotate: Bool { 58 | return false 59 | } 60 | 61 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 62 | return .portrait 63 | } 64 | 65 | override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { 66 | return .portrait 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Demo/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '15.6' 2 | inhibit_all_warnings! 3 | 4 | target 'Demo' do 5 | use_frameworks! 6 | 7 | pod 'UIAdapter', :path => "../" 8 | 9 | end 10 | -------------------------------------------------------------------------------- /Demo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - UIAdapter (1.4.0): 3 | - UIAdapter/Privacy (= 1.4.0) 4 | - UIAdapter/Privacy (1.4.0) 5 | 6 | DEPENDENCIES: 7 | - UIAdapter (from `../`) 8 | 9 | EXTERNAL SOURCES: 10 | UIAdapter: 11 | :path: "../" 12 | 13 | SPEC CHECKSUMS: 14 | UIAdapter: 81dd1efbab6c0d092ac0d02e12a3c6b84e3c3c99 15 | 16 | PODFILE CHECKSUM: 6c30ea2512eacb7800929df401f020c67f5b94ec 17 | 18 | COCOAPODS: 1.15.2 19 | -------------------------------------------------------------------------------- /Demo/Pods/Local Podspecs/AutoInch.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AutoInch", 3 | "version": "2.2.0", 4 | "summary": "优雅的iPhone 等比例/精准 适配工具", 5 | "homepage": "https://github.com/lixiang1994/AutoInch", 6 | "license": { 7 | "type": "MIT", 8 | "file": "LICENSE" 9 | }, 10 | "authors": { 11 | "LEE": "18611401994@163.com" 12 | }, 13 | "platforms": { 14 | "ios": "9.0" 15 | }, 16 | "source": { 17 | "git": "https://github.com/lixiang1994/AutoInch.git", 18 | "tag": "2.2.0" 19 | }, 20 | "source_files": "Sources/**/*.swift", 21 | "requires_arc": true, 22 | "frameworks": [ 23 | "UIKit", 24 | "Foundation" 25 | ], 26 | "swift_versions": [ 27 | "5.0" 28 | ], 29 | "swift_version": "5.0" 30 | } 31 | -------------------------------------------------------------------------------- /Demo/Pods/Local Podspecs/UIAdapter.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UIAdapter", 3 | "version": "1.4.0", 4 | "summary": "iOS屏幕适配工具", 5 | "homepage": "https://github.com/lixiang1994/UIAdapter", 6 | "license": { 7 | "type": "MIT", 8 | "file": "LICENSE" 9 | }, 10 | "authors": { 11 | "LEE": "18611401994@163.com" 12 | }, 13 | "platforms": { 14 | "ios": "9.0" 15 | }, 16 | "source": { 17 | "git": "https://github.com/lixiang1994/UIAdapter.git", 18 | "tag": "1.4.0" 19 | }, 20 | "source_files": "Sources/**/*.swift", 21 | "requires_arc": true, 22 | "swift_versions": "5.5", 23 | "cocoapods_version": ">= 1.4.0", 24 | "subspecs": [ 25 | { 26 | "name": "Privacy", 27 | "resource_bundles": { 28 | "UIAdapter": "Sources/PrivacyInfo.xcprivacy" 29 | } 30 | } 31 | ], 32 | "swift_version": "5.5" 33 | } 34 | -------------------------------------------------------------------------------- /Demo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - UIAdapter (1.4.0): 3 | - UIAdapter/Privacy (= 1.4.0) 4 | - UIAdapter/Privacy (1.4.0) 5 | 6 | DEPENDENCIES: 7 | - UIAdapter (from `../`) 8 | 9 | EXTERNAL SOURCES: 10 | UIAdapter: 11 | :path: "../" 12 | 13 | SPEC CHECKSUMS: 14 | UIAdapter: 81dd1efbab6c0d092ac0d02e12a3c6b84e3c3c99 15 | 16 | PODFILE CHECKSUM: 6c30ea2512eacb7800929df401f020c67f5b94ec 17 | 18 | COCOAPODS: 1.15.2 19 | -------------------------------------------------------------------------------- /Demo/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 182744467C38E9E907C9A7EFFB29169D /* UIAdapter.Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F41765D79284C40E260ED4D6BDFFDF7 /* UIAdapter.Screen.swift */; }; 11 | 19E14B07C75C62FCBA38FEE7411C3E77 /* Pods-Demo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3666E01CF3B1BB3B5EB22455C1F1E4F6 /* Pods-Demo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 337A2858AAF21867ACB1D08F7C18F07F /* UIAdapter-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BBD0CF16517CDE72429A64E120E050F /* UIAdapter-dummy.m */; }; 13 | 38701D9D0F5A9446697D6BF66A254EE1 /* UIAdapter-UIAdapter in Resources */ = {isa = PBXBuildFile; fileRef = C393B046E6897C8F915736BFC9917744 /* UIAdapter-UIAdapter */; }; 14 | 5DDC1F46BC098375EADAC45A953AE9A1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 15 | 6D202E79C44E47AFF7D1C4AA508ABAE8 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 37EC504FE85CCB6B7B9276AC69A04880 /* PrivacyInfo.xcprivacy */; }; 16 | AA0AD68F50A05B89C68B68C35CEB17B9 /* UIAdapter-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C6E02920A69A32E94C077118DAC03AA3 /* UIAdapter-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | DA0143DA5B5088970E5295266D8D1A86 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 18 | E94202714CC82FDF75807138703FFEAA /* UIAdapter.Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2DD5B3C1EBF1635105F41604DAE1522 /* UIAdapter.Zoom.swift */; }; 19 | F609DA23894C789CDCB0121BC8BEBA72 /* Pods-Demo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0B6886FC27E9B0BED9829A43F1D61 /* Pods-Demo-dummy.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 16B30789F879E669172CBBD0072EF0C0 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = EDDE0999C1764791CF0800260AD55218; 28 | remoteInfo = "UIAdapter-UIAdapter"; 29 | }; 30 | A999FA59A366AEDB3AEFDA1812D38294 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 3DD7B7CA7C05350D22AC11B09F3C5E56; 35 | remoteInfo = UIAdapter; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 06F3E5C6ECF6318B927DEBF7D3F68023 /* Pods-Demo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Demo-acknowledgements.plist"; sourceTree = ""; }; 41 | 0FC0B6886FC27E9B0BED9829A43F1D61 /* Pods-Demo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Demo-dummy.m"; sourceTree = ""; }; 42 | 12B5414F32669A4B7E2A7160C8C61061 /* UIAdapter */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = UIAdapter; path = UIAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 1BBD0CF16517CDE72429A64E120E050F /* UIAdapter-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "UIAdapter-dummy.m"; sourceTree = ""; }; 44 | 286FB7ED904A7A0E1C9B3D6791672A8D /* Pods-Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Demo.release.xcconfig"; sourceTree = ""; }; 45 | 3666E01CF3B1BB3B5EB22455C1F1E4F6 /* Pods-Demo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Demo-umbrella.h"; sourceTree = ""; }; 46 | 37EC504FE85CCB6B7B9276AC69A04880 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/PrivacyInfo.xcprivacy; sourceTree = ""; }; 47 | 3E368EBBBB8D0DEFEFF38A3743A7237A /* UIAdapter.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = UIAdapter.debug.xcconfig; sourceTree = ""; }; 48 | 3F41765D79284C40E260ED4D6BDFFDF7 /* UIAdapter.Screen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UIAdapter.Screen.swift; sourceTree = ""; }; 49 | 5D30FDAD8CECC381F32FF5F5B52175BC /* Pods-Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Demo.debug.xcconfig"; sourceTree = ""; }; 50 | 6764C79902817B8D9569F782CE6B98A6 /* UIAdapter-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UIAdapter-prefix.pch"; sourceTree = ""; }; 51 | 6F385BD1DF401013885E69CDFE731270 /* UIAdapter.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = UIAdapter.modulemap; sourceTree = ""; }; 52 | 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 53 | 77EBCE1FFE347A3644369F0343168C1D /* Pods-Demo-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Demo-frameworks.sh"; sourceTree = ""; }; 54 | 7E65ADC3B1644FF0F90473EEE697A2FF /* Pods-Demo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Demo.modulemap"; sourceTree = ""; }; 55 | 9A8F0B0C54577BA1BCF9ED9E2F5FFC1A /* UIAdapter-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "UIAdapter-Info.plist"; sourceTree = ""; }; 56 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 57 | A2DD5B3C1EBF1635105F41604DAE1522 /* UIAdapter.Zoom.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UIAdapter.Zoom.swift; sourceTree = ""; }; 58 | A5755CA6EB766B0CD852E86612513839 /* UIAdapter.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = UIAdapter.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 59 | B00FB3951EDA794D1FA5591F9AE58FC0 /* UIAdapter.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = UIAdapter.release.xcconfig; sourceTree = ""; }; 60 | C09550BE27F06DDA0FCBF43F3550A40A /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 61 | C393B046E6897C8F915736BFC9917744 /* UIAdapter-UIAdapter */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "UIAdapter-UIAdapter"; path = UIAdapter.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | C694DE63ED5EAB66E3CA6D184271692B /* Pods-Demo */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-Demo"; path = Pods_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | C6E02920A69A32E94C077118DAC03AA3 /* UIAdapter-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UIAdapter-umbrella.h"; sourceTree = ""; }; 64 | C92858FE026ED2D7FA214DF0079DFF16 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 65 | DB6E4016C1A5B01B4211686E89C59CA3 /* ResourceBundle-UIAdapter-UIAdapter-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-UIAdapter-UIAdapter-Info.plist"; sourceTree = ""; }; 66 | DDEDDEA5E8747667A9BBE52BA22B088D /* Pods-Demo-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Demo-Info.plist"; sourceTree = ""; }; 67 | E14C7B5E452F2DDF30E90A3950EE1807 /* Pods-Demo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Demo-acknowledgements.markdown"; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 3A39F62F9CD07578DE2E282591F36274 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | 5DDC1F46BC098375EADAC45A953AE9A1 /* Foundation.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 5CC24496F8AC62B132DF48EDB0ACC1CB /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | DA0143DA5B5088970E5295266D8D1A86 /* Foundation.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | C0E947BAC121797586AF0C642CE6235A /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | /* End PBXFrameworksBuildPhase section */ 95 | 96 | /* Begin PBXGroup section */ 97 | 21FF7982FCED7A76D3B9EB72011DACF2 /* Targets Support Files */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | A8DEFD83AB893CB86C8528E6037CB868 /* Pods-Demo */, 101 | ); 102 | name = "Targets Support Files"; 103 | sourceTree = ""; 104 | }; 105 | 578452D2E740E91742655AC8F1636D1F /* iOS */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, 109 | ); 110 | name = iOS; 111 | sourceTree = ""; 112 | }; 113 | 5B4AD5009FC4176B60D3308421DE4E48 /* Screen */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 3F41765D79284C40E260ED4D6BDFFDF7 /* UIAdapter.Screen.swift */, 117 | ); 118 | name = Screen; 119 | path = Sources/Screen; 120 | sourceTree = ""; 121 | }; 122 | 65C0D6BBC2BAF760852F2909910722CA /* Development Pods */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 71190A6489946A57581C98AC6568F8CF /* UIAdapter */, 126 | ); 127 | name = "Development Pods"; 128 | sourceTree = ""; 129 | }; 130 | 71190A6489946A57581C98AC6568F8CF /* UIAdapter */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 93063CB6F246C1440C6D652C5B933978 /* Pod */, 134 | C3EF43DD9608AC331FB30594FE57226D /* Privacy */, 135 | 5B4AD5009FC4176B60D3308421DE4E48 /* Screen */, 136 | 73D6C3906D9E34DEFEC052A58CFED0A6 /* Support Files */, 137 | D515C7D10C0B2E5BEED9AF6ED9CB674D /* Zoom */, 138 | ); 139 | name = UIAdapter; 140 | path = ../..; 141 | sourceTree = ""; 142 | }; 143 | 73D6C3906D9E34DEFEC052A58CFED0A6 /* Support Files */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | DB6E4016C1A5B01B4211686E89C59CA3 /* ResourceBundle-UIAdapter-UIAdapter-Info.plist */, 147 | 6F385BD1DF401013885E69CDFE731270 /* UIAdapter.modulemap */, 148 | 1BBD0CF16517CDE72429A64E120E050F /* UIAdapter-dummy.m */, 149 | 9A8F0B0C54577BA1BCF9ED9E2F5FFC1A /* UIAdapter-Info.plist */, 150 | 6764C79902817B8D9569F782CE6B98A6 /* UIAdapter-prefix.pch */, 151 | C6E02920A69A32E94C077118DAC03AA3 /* UIAdapter-umbrella.h */, 152 | 3E368EBBBB8D0DEFEFF38A3743A7237A /* UIAdapter.debug.xcconfig */, 153 | B00FB3951EDA794D1FA5591F9AE58FC0 /* UIAdapter.release.xcconfig */, 154 | ); 155 | name = "Support Files"; 156 | path = "Demo/Pods/Target Support Files/UIAdapter"; 157 | sourceTree = ""; 158 | }; 159 | 7D737ADCC6E45E1ED82B9C982AE95F53 /* Products */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | C694DE63ED5EAB66E3CA6D184271692B /* Pods-Demo */, 163 | 12B5414F32669A4B7E2A7160C8C61061 /* UIAdapter */, 164 | C393B046E6897C8F915736BFC9917744 /* UIAdapter-UIAdapter */, 165 | ); 166 | name = Products; 167 | sourceTree = ""; 168 | }; 169 | 93063CB6F246C1440C6D652C5B933978 /* Pod */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | C92858FE026ED2D7FA214DF0079DFF16 /* LICENSE */, 173 | C09550BE27F06DDA0FCBF43F3550A40A /* README.md */, 174 | A5755CA6EB766B0CD852E86612513839 /* UIAdapter.podspec */, 175 | ); 176 | name = Pod; 177 | sourceTree = ""; 178 | }; 179 | A8DEFD83AB893CB86C8528E6037CB868 /* Pods-Demo */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 7E65ADC3B1644FF0F90473EEE697A2FF /* Pods-Demo.modulemap */, 183 | E14C7B5E452F2DDF30E90A3950EE1807 /* Pods-Demo-acknowledgements.markdown */, 184 | 06F3E5C6ECF6318B927DEBF7D3F68023 /* Pods-Demo-acknowledgements.plist */, 185 | 0FC0B6886FC27E9B0BED9829A43F1D61 /* Pods-Demo-dummy.m */, 186 | 77EBCE1FFE347A3644369F0343168C1D /* Pods-Demo-frameworks.sh */, 187 | DDEDDEA5E8747667A9BBE52BA22B088D /* Pods-Demo-Info.plist */, 188 | 3666E01CF3B1BB3B5EB22455C1F1E4F6 /* Pods-Demo-umbrella.h */, 189 | 5D30FDAD8CECC381F32FF5F5B52175BC /* Pods-Demo.debug.xcconfig */, 190 | 286FB7ED904A7A0E1C9B3D6791672A8D /* Pods-Demo.release.xcconfig */, 191 | ); 192 | name = "Pods-Demo"; 193 | path = "Target Support Files/Pods-Demo"; 194 | sourceTree = ""; 195 | }; 196 | C3EF43DD9608AC331FB30594FE57226D /* Privacy */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 37EC504FE85CCB6B7B9276AC69A04880 /* PrivacyInfo.xcprivacy */, 200 | ); 201 | name = Privacy; 202 | sourceTree = ""; 203 | }; 204 | CF1408CF629C7361332E53B88F7BD30C = { 205 | isa = PBXGroup; 206 | children = ( 207 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, 208 | 65C0D6BBC2BAF760852F2909910722CA /* Development Pods */, 209 | D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, 210 | 7D737ADCC6E45E1ED82B9C982AE95F53 /* Products */, 211 | 21FF7982FCED7A76D3B9EB72011DACF2 /* Targets Support Files */, 212 | ); 213 | sourceTree = ""; 214 | }; 215 | D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 578452D2E740E91742655AC8F1636D1F /* iOS */, 219 | ); 220 | name = Frameworks; 221 | sourceTree = ""; 222 | }; 223 | D515C7D10C0B2E5BEED9AF6ED9CB674D /* Zoom */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | A2DD5B3C1EBF1635105F41604DAE1522 /* UIAdapter.Zoom.swift */, 227 | ); 228 | name = Zoom; 229 | path = Sources/Zoom; 230 | sourceTree = ""; 231 | }; 232 | /* End PBXGroup section */ 233 | 234 | /* Begin PBXHeadersBuildPhase section */ 235 | 42B5D843843EC01EF6ACFB0E666D9154 /* Headers */ = { 236 | isa = PBXHeadersBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | AA0AD68F50A05B89C68B68C35CEB17B9 /* UIAdapter-umbrella.h in Headers */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | 9427D557E407D1BC0B797AF994F42D6E /* Headers */ = { 244 | isa = PBXHeadersBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 19E14B07C75C62FCBA38FEE7411C3E77 /* Pods-Demo-umbrella.h in Headers */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | /* End PBXHeadersBuildPhase section */ 252 | 253 | /* Begin PBXNativeTarget section */ 254 | 380694B9ADC0CBB5D29A662EFE7F52C8 /* Pods-Demo */ = { 255 | isa = PBXNativeTarget; 256 | buildConfigurationList = 07B161ABB9C8D622AB1C1AF83FFF968B /* Build configuration list for PBXNativeTarget "Pods-Demo" */; 257 | buildPhases = ( 258 | 9427D557E407D1BC0B797AF994F42D6E /* Headers */, 259 | B6CE35D5169438981428D341B97986EF /* Sources */, 260 | 3A39F62F9CD07578DE2E282591F36274 /* Frameworks */, 261 | 02A2D7601F27E4C6E7EAB4589EF20365 /* Resources */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | 9884C022E6CF4ECE10E52397B9CB3B88 /* PBXTargetDependency */, 267 | ); 268 | name = "Pods-Demo"; 269 | productName = Pods_Demo; 270 | productReference = C694DE63ED5EAB66E3CA6D184271692B /* Pods-Demo */; 271 | productType = "com.apple.product-type.framework"; 272 | }; 273 | 3DD7B7CA7C05350D22AC11B09F3C5E56 /* UIAdapter */ = { 274 | isa = PBXNativeTarget; 275 | buildConfigurationList = 14C610886491602A34AA8B805A1B43DC /* Build configuration list for PBXNativeTarget "UIAdapter" */; 276 | buildPhases = ( 277 | 42B5D843843EC01EF6ACFB0E666D9154 /* Headers */, 278 | 6C58F47930A2703018EBCF060C6F7C9A /* Sources */, 279 | 5CC24496F8AC62B132DF48EDB0ACC1CB /* Frameworks */, 280 | 60968CEFBCC25055C68CC73345E82E9B /* Resources */, 281 | ); 282 | buildRules = ( 283 | ); 284 | dependencies = ( 285 | E532E3D1EF2CA2D0EAEFFAB1796A05B0 /* PBXTargetDependency */, 286 | ); 287 | name = UIAdapter; 288 | productName = UIAdapter; 289 | productReference = 12B5414F32669A4B7E2A7160C8C61061 /* UIAdapter */; 290 | productType = "com.apple.product-type.framework"; 291 | }; 292 | EDDE0999C1764791CF0800260AD55218 /* UIAdapter-UIAdapter */ = { 293 | isa = PBXNativeTarget; 294 | buildConfigurationList = 92A514A7CF93704A34F2F3041C9B6ADA /* Build configuration list for PBXNativeTarget "UIAdapter-UIAdapter" */; 295 | buildPhases = ( 296 | 6C46C77BDF51E07A7A6AFECA96BD674D /* Sources */, 297 | C0E947BAC121797586AF0C642CE6235A /* Frameworks */, 298 | 4E7B05C70F1F7D03850AEEF34601AF17 /* Resources */, 299 | ); 300 | buildRules = ( 301 | ); 302 | dependencies = ( 303 | ); 304 | name = "UIAdapter-UIAdapter"; 305 | productName = UIAdapter; 306 | productReference = C393B046E6897C8F915736BFC9917744 /* UIAdapter-UIAdapter */; 307 | productType = "com.apple.product-type.bundle"; 308 | }; 309 | /* End PBXNativeTarget section */ 310 | 311 | /* Begin PBXProject section */ 312 | BFDFE7DC352907FC980B868725387E98 /* Project object */ = { 313 | isa = PBXProject; 314 | attributes = { 315 | LastSwiftUpdateCheck = 1500; 316 | LastUpgradeCheck = 1500; 317 | }; 318 | buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; 319 | compatibilityVersion = "Xcode 11.0"; 320 | developmentRegion = en; 321 | hasScannedForEncodings = 0; 322 | knownRegions = ( 323 | Base, 324 | en, 325 | ); 326 | mainGroup = CF1408CF629C7361332E53B88F7BD30C; 327 | minimizedProjectReferenceProxies = 0; 328 | productRefGroup = 7D737ADCC6E45E1ED82B9C982AE95F53 /* Products */; 329 | projectDirPath = ""; 330 | projectRoot = ""; 331 | targets = ( 332 | 380694B9ADC0CBB5D29A662EFE7F52C8 /* Pods-Demo */, 333 | 3DD7B7CA7C05350D22AC11B09F3C5E56 /* UIAdapter */, 334 | EDDE0999C1764791CF0800260AD55218 /* UIAdapter-UIAdapter */, 335 | ); 336 | }; 337 | /* End PBXProject section */ 338 | 339 | /* Begin PBXResourcesBuildPhase section */ 340 | 02A2D7601F27E4C6E7EAB4589EF20365 /* Resources */ = { 341 | isa = PBXResourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | 4E7B05C70F1F7D03850AEEF34601AF17 /* Resources */ = { 348 | isa = PBXResourcesBuildPhase; 349 | buildActionMask = 2147483647; 350 | files = ( 351 | 6D202E79C44E47AFF7D1C4AA508ABAE8 /* PrivacyInfo.xcprivacy in Resources */, 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | 60968CEFBCC25055C68CC73345E82E9B /* Resources */ = { 356 | isa = PBXResourcesBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | 38701D9D0F5A9446697D6BF66A254EE1 /* UIAdapter-UIAdapter in Resources */, 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | }; 363 | /* End PBXResourcesBuildPhase section */ 364 | 365 | /* Begin PBXSourcesBuildPhase section */ 366 | 6C46C77BDF51E07A7A6AFECA96BD674D /* Sources */ = { 367 | isa = PBXSourcesBuildPhase; 368 | buildActionMask = 2147483647; 369 | files = ( 370 | ); 371 | runOnlyForDeploymentPostprocessing = 0; 372 | }; 373 | 6C58F47930A2703018EBCF060C6F7C9A /* Sources */ = { 374 | isa = PBXSourcesBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | 337A2858AAF21867ACB1D08F7C18F07F /* UIAdapter-dummy.m in Sources */, 378 | 182744467C38E9E907C9A7EFFB29169D /* UIAdapter.Screen.swift in Sources */, 379 | E94202714CC82FDF75807138703FFEAA /* UIAdapter.Zoom.swift in Sources */, 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | B6CE35D5169438981428D341B97986EF /* Sources */ = { 384 | isa = PBXSourcesBuildPhase; 385 | buildActionMask = 2147483647; 386 | files = ( 387 | F609DA23894C789CDCB0121BC8BEBA72 /* Pods-Demo-dummy.m in Sources */, 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | }; 391 | /* End PBXSourcesBuildPhase section */ 392 | 393 | /* Begin PBXTargetDependency section */ 394 | 9884C022E6CF4ECE10E52397B9CB3B88 /* PBXTargetDependency */ = { 395 | isa = PBXTargetDependency; 396 | name = UIAdapter; 397 | target = 3DD7B7CA7C05350D22AC11B09F3C5E56 /* UIAdapter */; 398 | targetProxy = A999FA59A366AEDB3AEFDA1812D38294 /* PBXContainerItemProxy */; 399 | }; 400 | E532E3D1EF2CA2D0EAEFFAB1796A05B0 /* PBXTargetDependency */ = { 401 | isa = PBXTargetDependency; 402 | name = "UIAdapter-UIAdapter"; 403 | target = EDDE0999C1764791CF0800260AD55218 /* UIAdapter-UIAdapter */; 404 | targetProxy = 16B30789F879E669172CBBD0072EF0C0 /* PBXContainerItemProxy */; 405 | }; 406 | /* End PBXTargetDependency section */ 407 | 408 | /* Begin XCBuildConfiguration section */ 409 | 01829462C825D2F51DF59BD8DB8ED758 /* Debug */ = { 410 | isa = XCBuildConfiguration; 411 | baseConfigurationReference = 3E368EBBBB8D0DEFEFF38A3743A7237A /* UIAdapter.debug.xcconfig */; 412 | buildSettings = { 413 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 414 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 415 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 416 | CURRENT_PROJECT_VERSION = 1; 417 | DEFINES_MODULE = YES; 418 | DYLIB_COMPATIBILITY_VERSION = 1; 419 | DYLIB_CURRENT_VERSION = 1; 420 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 421 | GCC_PREFIX_HEADER = "Target Support Files/UIAdapter/UIAdapter-prefix.pch"; 422 | INFOPLIST_FILE = "Target Support Files/UIAdapter/UIAdapter-Info.plist"; 423 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 424 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 425 | LD_RUNPATH_SEARCH_PATHS = ( 426 | "$(inherited)", 427 | "@executable_path/Frameworks", 428 | "@loader_path/Frameworks", 429 | ); 430 | MODULEMAP_FILE = "Target Support Files/UIAdapter/UIAdapter.modulemap"; 431 | PRODUCT_MODULE_NAME = UIAdapter; 432 | PRODUCT_NAME = UIAdapter; 433 | SDKROOT = iphoneos; 434 | SKIP_INSTALL = YES; 435 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 436 | SWIFT_VERSION = 5.5; 437 | TARGETED_DEVICE_FAMILY = "1,2"; 438 | VERSIONING_SYSTEM = "apple-generic"; 439 | VERSION_INFO_PREFIX = ""; 440 | }; 441 | name = Debug; 442 | }; 443 | 44A4B2FB6211B90C1949A44A381F6D1F /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 448 | CLANG_ANALYZER_NONNULL = YES; 449 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 450 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 451 | CLANG_CXX_LIBRARY = "libc++"; 452 | CLANG_ENABLE_MODULES = YES; 453 | CLANG_ENABLE_OBJC_ARC = YES; 454 | CLANG_ENABLE_OBJC_WEAK = YES; 455 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 456 | CLANG_WARN_BOOL_CONVERSION = YES; 457 | CLANG_WARN_COMMA = YES; 458 | CLANG_WARN_CONSTANT_CONVERSION = YES; 459 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 460 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 461 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 462 | CLANG_WARN_EMPTY_BODY = YES; 463 | CLANG_WARN_ENUM_CONVERSION = YES; 464 | CLANG_WARN_INFINITE_RECURSION = YES; 465 | CLANG_WARN_INT_CONVERSION = YES; 466 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 467 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 468 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 469 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 470 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 471 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 472 | CLANG_WARN_STRICT_PROTOTYPES = YES; 473 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 474 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 475 | CLANG_WARN_UNREACHABLE_CODE = YES; 476 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 477 | COPY_PHASE_STRIP = NO; 478 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 479 | ENABLE_NS_ASSERTIONS = NO; 480 | ENABLE_STRICT_OBJC_MSGSEND = YES; 481 | GCC_C_LANGUAGE_STANDARD = gnu11; 482 | GCC_NO_COMMON_BLOCKS = YES; 483 | GCC_PREPROCESSOR_DEFINITIONS = ( 484 | "POD_CONFIGURATION_RELEASE=1", 485 | "$(inherited)", 486 | ); 487 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 488 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 489 | GCC_WARN_UNDECLARED_SELECTOR = YES; 490 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 491 | GCC_WARN_UNUSED_FUNCTION = YES; 492 | GCC_WARN_UNUSED_VARIABLE = YES; 493 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 494 | MTL_ENABLE_DEBUG_INFO = NO; 495 | MTL_FAST_MATH = YES; 496 | PRODUCT_NAME = "$(TARGET_NAME)"; 497 | STRIP_INSTALLED_PRODUCT = NO; 498 | SWIFT_COMPILATION_MODE = wholemodule; 499 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 500 | SWIFT_VERSION = 5.0; 501 | SYMROOT = "${SRCROOT}/../build"; 502 | }; 503 | name = Release; 504 | }; 505 | 78D1B8A770E194D2DC906100D47C348C /* Debug */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 5D30FDAD8CECC381F32FF5F5B52175BC /* Pods-Demo.debug.xcconfig */; 508 | buildSettings = { 509 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 510 | CLANG_ENABLE_OBJC_WEAK = NO; 511 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 512 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 513 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 514 | CURRENT_PROJECT_VERSION = 1; 515 | DEFINES_MODULE = YES; 516 | DYLIB_COMPATIBILITY_VERSION = 1; 517 | DYLIB_CURRENT_VERSION = 1; 518 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 519 | INFOPLIST_FILE = "Target Support Files/Pods-Demo/Pods-Demo-Info.plist"; 520 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 521 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 522 | LD_RUNPATH_SEARCH_PATHS = ( 523 | "$(inherited)", 524 | "@executable_path/Frameworks", 525 | "@loader_path/Frameworks", 526 | ); 527 | MACH_O_TYPE = staticlib; 528 | MODULEMAP_FILE = "Target Support Files/Pods-Demo/Pods-Demo.modulemap"; 529 | OTHER_LDFLAGS = ""; 530 | OTHER_LIBTOOLFLAGS = ""; 531 | PODS_ROOT = "$(SRCROOT)"; 532 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 533 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 534 | SDKROOT = iphoneos; 535 | SKIP_INSTALL = YES; 536 | TARGETED_DEVICE_FAMILY = "1,2"; 537 | VERSIONING_SYSTEM = "apple-generic"; 538 | VERSION_INFO_PREFIX = ""; 539 | }; 540 | name = Debug; 541 | }; 542 | 85ACE9A8321DAE0EDB30EC34086D4B8F /* Release */ = { 543 | isa = XCBuildConfiguration; 544 | baseConfigurationReference = 286FB7ED904A7A0E1C9B3D6791672A8D /* Pods-Demo.release.xcconfig */; 545 | buildSettings = { 546 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 547 | CLANG_ENABLE_OBJC_WEAK = NO; 548 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 549 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 550 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 551 | CURRENT_PROJECT_VERSION = 1; 552 | DEFINES_MODULE = YES; 553 | DYLIB_COMPATIBILITY_VERSION = 1; 554 | DYLIB_CURRENT_VERSION = 1; 555 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 556 | INFOPLIST_FILE = "Target Support Files/Pods-Demo/Pods-Demo-Info.plist"; 557 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 558 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 559 | LD_RUNPATH_SEARCH_PATHS = ( 560 | "$(inherited)", 561 | "@executable_path/Frameworks", 562 | "@loader_path/Frameworks", 563 | ); 564 | MACH_O_TYPE = staticlib; 565 | MODULEMAP_FILE = "Target Support Files/Pods-Demo/Pods-Demo.modulemap"; 566 | OTHER_LDFLAGS = ""; 567 | OTHER_LIBTOOLFLAGS = ""; 568 | PODS_ROOT = "$(SRCROOT)"; 569 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 570 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 571 | SDKROOT = iphoneos; 572 | SKIP_INSTALL = YES; 573 | TARGETED_DEVICE_FAMILY = "1,2"; 574 | VALIDATE_PRODUCT = YES; 575 | VERSIONING_SYSTEM = "apple-generic"; 576 | VERSION_INFO_PREFIX = ""; 577 | }; 578 | name = Release; 579 | }; 580 | 886B5524BF195B309F19EC6019BBE94C /* Release */ = { 581 | isa = XCBuildConfiguration; 582 | baseConfigurationReference = B00FB3951EDA794D1FA5591F9AE58FC0 /* UIAdapter.release.xcconfig */; 583 | buildSettings = { 584 | CODE_SIGNING_ALLOWED = NO; 585 | CODE_SIGN_IDENTITY = "Apple Distribution"; 586 | CODE_SIGN_STYLE = Automatic; 587 | CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/UIAdapter"; 588 | DEVELOPMENT_TEAM = 8G74YECJ4Z; 589 | IBSC_MODULE = UIAdapter; 590 | INFOPLIST_FILE = "Target Support Files/UIAdapter/ResourceBundle-UIAdapter-UIAdapter-Info.plist"; 591 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 592 | PRODUCT_NAME = UIAdapter; 593 | SDKROOT = iphoneos; 594 | SKIP_INSTALL = YES; 595 | TARGETED_DEVICE_FAMILY = "1,2"; 596 | WRAPPER_EXTENSION = bundle; 597 | }; 598 | name = Release; 599 | }; 600 | 9FE93BEA49F98F59B5883EDD01C68DCA /* Release */ = { 601 | isa = XCBuildConfiguration; 602 | baseConfigurationReference = B00FB3951EDA794D1FA5591F9AE58FC0 /* UIAdapter.release.xcconfig */; 603 | buildSettings = { 604 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 605 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 606 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 607 | CURRENT_PROJECT_VERSION = 1; 608 | DEFINES_MODULE = YES; 609 | DYLIB_COMPATIBILITY_VERSION = 1; 610 | DYLIB_CURRENT_VERSION = 1; 611 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 612 | GCC_PREFIX_HEADER = "Target Support Files/UIAdapter/UIAdapter-prefix.pch"; 613 | INFOPLIST_FILE = "Target Support Files/UIAdapter/UIAdapter-Info.plist"; 614 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 615 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 616 | LD_RUNPATH_SEARCH_PATHS = ( 617 | "$(inherited)", 618 | "@executable_path/Frameworks", 619 | "@loader_path/Frameworks", 620 | ); 621 | MODULEMAP_FILE = "Target Support Files/UIAdapter/UIAdapter.modulemap"; 622 | PRODUCT_MODULE_NAME = UIAdapter; 623 | PRODUCT_NAME = UIAdapter; 624 | SDKROOT = iphoneos; 625 | SKIP_INSTALL = YES; 626 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 627 | SWIFT_VERSION = 5.5; 628 | TARGETED_DEVICE_FAMILY = "1,2"; 629 | VALIDATE_PRODUCT = YES; 630 | VERSIONING_SYSTEM = "apple-generic"; 631 | VERSION_INFO_PREFIX = ""; 632 | }; 633 | name = Release; 634 | }; 635 | A0DC1C2C814704734F83EAB35BB20B21 /* Debug */ = { 636 | isa = XCBuildConfiguration; 637 | buildSettings = { 638 | ALWAYS_SEARCH_USER_PATHS = NO; 639 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 640 | CLANG_ANALYZER_NONNULL = YES; 641 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 642 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 643 | CLANG_CXX_LIBRARY = "libc++"; 644 | CLANG_ENABLE_MODULES = YES; 645 | CLANG_ENABLE_OBJC_ARC = YES; 646 | CLANG_ENABLE_OBJC_WEAK = YES; 647 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 648 | CLANG_WARN_BOOL_CONVERSION = YES; 649 | CLANG_WARN_COMMA = YES; 650 | CLANG_WARN_CONSTANT_CONVERSION = YES; 651 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 652 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 653 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 654 | CLANG_WARN_EMPTY_BODY = YES; 655 | CLANG_WARN_ENUM_CONVERSION = YES; 656 | CLANG_WARN_INFINITE_RECURSION = YES; 657 | CLANG_WARN_INT_CONVERSION = YES; 658 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 659 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 660 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 661 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 662 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 663 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 664 | CLANG_WARN_STRICT_PROTOTYPES = YES; 665 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 666 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 667 | CLANG_WARN_UNREACHABLE_CODE = YES; 668 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 669 | COPY_PHASE_STRIP = NO; 670 | DEBUG_INFORMATION_FORMAT = dwarf; 671 | ENABLE_STRICT_OBJC_MSGSEND = YES; 672 | ENABLE_TESTABILITY = YES; 673 | GCC_C_LANGUAGE_STANDARD = gnu11; 674 | GCC_DYNAMIC_NO_PIC = NO; 675 | GCC_NO_COMMON_BLOCKS = YES; 676 | GCC_OPTIMIZATION_LEVEL = 0; 677 | GCC_PREPROCESSOR_DEFINITIONS = ( 678 | "POD_CONFIGURATION_DEBUG=1", 679 | "DEBUG=1", 680 | "$(inherited)", 681 | ); 682 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 683 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 684 | GCC_WARN_UNDECLARED_SELECTOR = YES; 685 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 686 | GCC_WARN_UNUSED_FUNCTION = YES; 687 | GCC_WARN_UNUSED_VARIABLE = YES; 688 | IPHONEOS_DEPLOYMENT_TARGET = 15.6; 689 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 690 | MTL_FAST_MATH = YES; 691 | ONLY_ACTIVE_ARCH = YES; 692 | PRODUCT_NAME = "$(TARGET_NAME)"; 693 | STRIP_INSTALLED_PRODUCT = NO; 694 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 695 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 696 | SWIFT_VERSION = 5.0; 697 | SYMROOT = "${SRCROOT}/../build"; 698 | }; 699 | name = Debug; 700 | }; 701 | BB0EE533CA798C938695144DF04CF65D /* Debug */ = { 702 | isa = XCBuildConfiguration; 703 | baseConfigurationReference = 3E368EBBBB8D0DEFEFF38A3743A7237A /* UIAdapter.debug.xcconfig */; 704 | buildSettings = { 705 | CODE_SIGNING_ALLOWED = NO; 706 | CODE_SIGN_IDENTITY = "Apple Development"; 707 | CODE_SIGN_STYLE = Automatic; 708 | CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/UIAdapter"; 709 | DEVELOPMENT_TEAM = 8G74YECJ4Z; 710 | IBSC_MODULE = UIAdapter; 711 | INFOPLIST_FILE = "Target Support Files/UIAdapter/ResourceBundle-UIAdapter-UIAdapter-Info.plist"; 712 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 713 | PRODUCT_NAME = UIAdapter; 714 | SDKROOT = iphoneos; 715 | SKIP_INSTALL = YES; 716 | TARGETED_DEVICE_FAMILY = "1,2"; 717 | WRAPPER_EXTENSION = bundle; 718 | }; 719 | name = Debug; 720 | }; 721 | /* End XCBuildConfiguration section */ 722 | 723 | /* Begin XCConfigurationList section */ 724 | 07B161ABB9C8D622AB1C1AF83FFF968B /* Build configuration list for PBXNativeTarget "Pods-Demo" */ = { 725 | isa = XCConfigurationList; 726 | buildConfigurations = ( 727 | 78D1B8A770E194D2DC906100D47C348C /* Debug */, 728 | 85ACE9A8321DAE0EDB30EC34086D4B8F /* Release */, 729 | ); 730 | defaultConfigurationIsVisible = 0; 731 | defaultConfigurationName = Release; 732 | }; 733 | 14C610886491602A34AA8B805A1B43DC /* Build configuration list for PBXNativeTarget "UIAdapter" */ = { 734 | isa = XCConfigurationList; 735 | buildConfigurations = ( 736 | 01829462C825D2F51DF59BD8DB8ED758 /* Debug */, 737 | 9FE93BEA49F98F59B5883EDD01C68DCA /* Release */, 738 | ); 739 | defaultConfigurationIsVisible = 0; 740 | defaultConfigurationName = Release; 741 | }; 742 | 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { 743 | isa = XCConfigurationList; 744 | buildConfigurations = ( 745 | A0DC1C2C814704734F83EAB35BB20B21 /* Debug */, 746 | 44A4B2FB6211B90C1949A44A381F6D1F /* Release */, 747 | ); 748 | defaultConfigurationIsVisible = 0; 749 | defaultConfigurationName = Release; 750 | }; 751 | 92A514A7CF93704A34F2F3041C9B6ADA /* Build configuration list for PBXNativeTarget "UIAdapter-UIAdapter" */ = { 752 | isa = XCConfigurationList; 753 | buildConfigurations = ( 754 | BB0EE533CA798C938695144DF04CF65D /* Debug */, 755 | 886B5524BF195B309F19EC6019BBE94C /* Release */, 756 | ); 757 | defaultConfigurationIsVisible = 0; 758 | defaultConfigurationName = Release; 759 | }; 760 | /* End XCConfigurationList section */ 761 | }; 762 | rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; 763 | } 764 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## UIAdapter 5 | 6 | MIT License 7 | 8 | Copyright (c) 2021 LEE 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2021 LEE 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | UIAdapter 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Demo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Demo 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/UIAdapter/UIAdapter.framework -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UIAdapter.framework -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/UIAdapter/UIAdapter.framework -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UIAdapter.framework -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink -f "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 116 | mkdir -p "${DWARF_DSYM_FOLDER_PATH}" 117 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 118 | fi 119 | fi 120 | } 121 | 122 | # Used as a return value for each invocation of `strip_invalid_archs` function. 123 | STRIP_BINARY_RETVAL=0 124 | 125 | # Strip invalid architectures 126 | strip_invalid_archs() { 127 | binary="$1" 128 | warn_missing_arch=${2:-true} 129 | # Get architectures for current target binary 130 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 131 | # Intersect them with the architectures we are building for 132 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 133 | # If there are no archs supported by this binary then warn the user 134 | if [[ -z "$intersected_archs" ]]; then 135 | if [[ "$warn_missing_arch" == "true" ]]; then 136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 137 | fi 138 | STRIP_BINARY_RETVAL=1 139 | return 140 | fi 141 | stripped="" 142 | for arch in $binary_archs; do 143 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 144 | # Strip non-valid architectures in-place 145 | lipo -remove "$arch" -output "$binary" "$binary" 146 | stripped="$stripped $arch" 147 | fi 148 | done 149 | if [[ "$stripped" ]]; then 150 | echo "Stripped $binary of architectures:$stripped" 151 | fi 152 | STRIP_BINARY_RETVAL=0 153 | } 154 | 155 | # Copies the bcsymbolmap files of a vendored framework 156 | install_bcsymbolmap() { 157 | local bcsymbolmap_path="$1" 158 | local destination="${BUILT_PRODUCTS_DIR}" 159 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 160 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 161 | } 162 | 163 | # Signs a framework with the provided identity 164 | code_sign_if_enabled() { 165 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 166 | # Use the current code_sign_identity 167 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 168 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 169 | 170 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 171 | code_sign_cmd="$code_sign_cmd &" 172 | fi 173 | echo "$code_sign_cmd" 174 | eval "$code_sign_cmd" 175 | fi 176 | } 177 | 178 | if [[ "$CONFIGURATION" == "Debug" ]]; then 179 | install_framework "${BUILT_PRODUCTS_DIR}/UIAdapter/UIAdapter.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/UIAdapter/UIAdapter.framework" 183 | fi 184 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 185 | wait 186 | fi 187 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_DemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_DemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter/UIAdapter.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter/UIAdapter.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter" 9 | OTHER_LDFLAGS = $(inherited) -framework "UIAdapter" 10 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 11 | PODS_BUILD_DIR = ${BUILD_DIR} 12 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 13 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 14 | PODS_ROOT = ${SRCROOT}/Pods 15 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Demo { 2 | umbrella header "Pods-Demo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter/UIAdapter.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter/UIAdapter.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter" 9 | OTHER_LDFLAGS = $(inherited) -framework "UIAdapter" 10 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 11 | PODS_BUILD_DIR = ${BUILD_DIR} 12 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 13 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 14 | PODS_ROOT = ${SRCROOT}/Pods 15 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/ResourceBundle-Privacy-UIAdapter-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 7 | CFBundleIdentifier 8 | ${PRODUCT_BUNDLE_IDENTIFIER} 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ${PRODUCT_NAME} 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.3.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/ResourceBundle-UIAdapter-UIAdapter-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 7 | CFBundleIdentifier 8 | ${PRODUCT_BUNDLE_IDENTIFIER} 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ${PRODUCT_NAME} 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.4.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_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 | FMWK 17 | CFBundleShortVersionString 18 | 1.4.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_UIAdapter : NSObject 3 | @end 4 | @implementation PodsDummy_UIAdapter 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double UIAdapterVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char UIAdapterVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter.modulemap: -------------------------------------------------------------------------------- 1 | framework module UIAdapter { 2 | umbrella header "UIAdapter-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/UIAdapter/UIAdapter.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/UIAdapter 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 LEE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.5 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "UIAdapter", 8 | platforms: [.iOS(.v9)], 9 | products: [ 10 | // Products define the executables and libraries a package produces, and make them visible to other packages. 11 | .library( 12 | name: "UIAdapter", 13 | targets: ["UIAdapter"]), 14 | ], 15 | dependencies: [ 16 | // Dependencies declare other packages that this package depends on. 17 | // .package(url: /* package url */, from: "1.0.0"), 18 | ], 19 | targets: [ 20 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 21 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 22 | .target( 23 | name: "UIAdapter", 24 | dependencies: [], 25 | path: "Sources", 26 | resources: [.process("PrivacyInfo.xcprivacy")] 27 | ) 28 | ] 29 | ) 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UIAdapter - An elegant solution to the iOS screen adaptation problem 2 | 3 | [![License](https://img.shields.io/cocoapods/l/UIAdapter.svg)](LICENSE)  4 | ![Swift](https://img.shields.io/badge/Swift-5.2-orange.svg)  5 | ![Platform](https://img.shields.io/cocoapods/p/UIAdapter.svg?style=flat)  6 | [![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-4BC51D.svg?style=flat")](https://swift.org/package-manager/)  7 | [![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)  8 | [![Cocoapods](https://img.shields.io/cocoapods/v/UIAdapter.svg)](https://cocoapods.org) 9 | 10 | ## [:cn:天朝子民](README_CN.md) 11 | 12 | ## Features 13 | 14 | - [x] Numerical type fast conversion 15 | - [x] Storyboard equal scale adaptation 16 | - [x] Xib equal scale adaptation 17 | - [x] Custom calculation processing 18 | - [x] Quick match for each screen size type 19 | 20 | 21 | ## Installation 22 | 23 | **CocoaPods - Podfile** 24 | 25 | ```ruby 26 | pod 'UIAdapter' 27 | ``` 28 | 29 | **Carthage - Cartfile** 30 | 31 | ```ruby 32 | github "lixiang1994/UIAdapter" 33 | ``` 34 | 35 | #### [Swift Package Manager for Apple platforms](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) 36 | 37 | Select Xcode menu `File > Swift Packages > Add Package Dependency` and enter repository URL with GUI. 38 | ``` 39 | Repository: https://github.com/lixiang1994/UIAdapter 40 | ``` 41 | 42 | #### [Swift Package Manager](https://swift.org/package-manager/) 43 | 44 | Add the following to the dependencies of your `Package.swift`: 45 | ```swift 46 | .package(url: "https://github.com/lixiang1994/UIAdapter.git", from: "version") 47 | ``` 48 | 49 | ## Usage 50 | 51 | First make sure to import the framework: 52 | 53 | ```swift 54 | import UIAdapter 55 | ``` 56 | 57 | Here are some usage examples. All devices are also available as simulators: 58 | 59 | 60 | ### Zoom 61 | 62 | 63 | AutoLayout (SnapKit): 64 | 65 | ```swift 66 | private func setupLayout() { 67 | cardView.snp.makeConstraints { (make) in 68 | make.top.equalTo(16.zoom()) 69 | make.left.right.equalToSuperview().inset(15.zoom()) 70 | make.bottom.equalTo(-26.zoom()) 71 | } 72 | 73 | lineView.snp.makeConstraints { (make) in 74 | make.left.right.equalToSuperview().inset(15.zoom()) 75 | make.top.equalTo(titleLabel.snp.bottom) 76 | make.height.equalTo(1) 77 | } 78 | 79 | titleLabel.snp.makeConstraints { (make) in 80 | make.top.equalToSuperview() 81 | make.left.equalTo(15.zoom()) 82 | make.height.equalTo(48.zoom()) 83 | } 84 | 85 | stateLabel.snp.makeConstraints { (make) in 86 | make.top.equalTo(lineView).offset(10.zoom()) 87 | make.left.equalTo(15.zoom()) 88 | make.height.equalTo(15.zoom()) 89 | } 90 | } 91 | ``` 92 | 93 | Property (Then): 94 | 95 | ```swift 96 | private lazy var cardView = UIView().then { 97 | $0.cornerRadius = 6.zoom() 98 | $0.backgroundColor = .white 99 | } 100 | 101 | private lazy var lineView = UIView().then { 102 | $0.backgroundColor = .hex("000000", alpha: 0.05) 103 | } 104 | 105 | private lazy var titleLabel = UILabel().then { 106 | $0.textColor = .black 107 | $0.font = .systemFont(ofSize: 20.zoom(), weight: .medium) 108 | } 109 | 110 | private lazy var stateLabel = UILabel().then { 111 | $0.textColor = .gray 112 | $0.font = .systemFont(ofSize: 12.zoom(), weight: .medium) 113 | } 114 | ``` 115 | 116 | Storyboard / Xib: 117 | 118 | ![Constraint](Resources/Storyboard%20Constraint.png) 119 | ![UILabel Font](Resources/Storyboard%20Label%20Font.png) 120 | 121 | ### Screen 122 | 123 | e.g. 124 | 125 | ```swift 126 | // default other screen numberOfLines = 0 127 | // 3.5 inches screen numberOfLines = 1 128 | // 4.0 inches screen numberOfLines = 2 129 | label.numberOfLines = 0.screen.inch(._3_5, is: 1).inch(._4_0, is: 2).value 130 | ``` 131 | 132 | 133 | ```swift 134 | // default other screen numberOfLines = 0 135 | // width 320 screen numberOfLines = 1 136 | // width 375 screen numberOfLines = 2 137 | label.numberOfLines = 0.screen.width(equalTo: 375, is: 1).width(equalTo: 375, is: 2).value 138 | ``` 139 | 140 | 141 | ```swift 142 | print("this is " + "default".screen 143 | .width(equalTo: 375, is: "width equal to 375") 144 | .width(lessThan: 414, is: "width less than 414") 145 | .width(greaterThan: 414, is: "width greater than 414") 146 | .height(equalTo: 700, is: "height equal to 375") 147 | .height(lessThan: 844, is: "height less than 844") 148 | .height(greaterThan: 844, is: "height greater than 844") 149 | .inch(._4_7, is: "4.7-inch") 150 | .inch(._5_8, is: "5.8-inch") 151 | .inch(._6_5, is: "6.5-inch") 152 | .level(.compact, is: "screen (4:3)") 153 | .level(.regular, is: "screen (16:9)") 154 | .level(.full, is: "screen (19.5:9)") 155 | .value 156 | ) 157 | ``` 158 | 159 | 160 | ## Screenshot 161 | 162 | ![TikTok 1](Resources/Storyboard%20TikTok%20Demo1.jpg) 163 | 164 | ![TikTok 2](Resources/Storyboard%20TikTok%20Demo2.jpg) 165 | 166 | ## Contributing 167 | 168 | If you have the need for a specific feature that you want implemented or if you experienced a bug, please open an issue. 169 | If you extended the functionality of UIAdapter yourself and want others to use it too, please submit a pull request. 170 | 171 | 172 | ## License 173 | 174 | UIAdapter is under MIT license. See the [LICENSE](LICENSE) file for more info. 175 | 176 | 177 | >### [相关文章 Inch](https://www.jianshu.com/p/d2c09cb65ef7) 178 | >### [相关文章 Auto](https://www.jianshu.com/p/e0e12206e0c7) 179 | >### [相关文章 Auto](https://www.jianshu.com/p/48c67d0c95b6) 180 | 181 | ----- 182 | 183 | > ## 欢迎入群交流 184 | ![QQ](https://github.com/lixiang1994/Resources/blob/master/QQClub/QQClub.JPG) 185 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | # UIAdapter - 优雅的iOS界面等比例缩放屏幕适配方案 2 | 3 | [![License](https://img.shields.io/cocoapods/l/UIAdapter.svg)](LICENSE)  4 | ![Swift](https://img.shields.io/badge/Swift-5.2-orange.svg)  5 | ![Platform](https://img.shields.io/cocoapods/p/UIAdapter.svg?style=flat)  6 | [![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-4BC51D.svg?style=flat")](https://swift.org/package-manager/)  7 | [![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)  8 | [![Cocoapods](https://img.shields.io/cocoapods/v/UIAdapter.svg)](https://cocoapods.org) 9 | 10 | ## 特性 11 | 12 | - [x] 数值类型快速转换 13 | - [x] Storyboard 等比例缩放适配支持 14 | - [x] Xib 等比例缩放适配支持 15 | - [x] 自定义缩放计算处理 16 | - [x] 各个屏幕尺寸快速匹配 17 | 18 | 19 | ## 安装 20 | 21 | **CocoaPods - Podfile** 22 | 23 | ```ruby 24 | pod 'UIAdapter' 25 | ``` 26 | 27 | **Carthage - Cartfile** 28 | 29 | ```ruby 30 | github "lixiang1994/UIAdapter" 31 | ``` 32 | 33 | #### [Swift Package Manager for Apple platforms](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) 34 | 35 | 选择 Xcode 菜单 `File > Swift Packages > Add Package Dependency` 输入仓库地址. 36 | ``` 37 | Repository: https://github.com/lixiang1994/UIAdapter 38 | ``` 39 | 40 | #### [Swift Package Manager](https://swift.org/package-manager/) 41 | 42 | 将以下内容添加到你的 `Package.swift`: 43 | ```swift 44 | .package(url: "https://github.com/lixiang1994/UIAdapter.git", from: "version") 45 | ``` 46 | 47 | ## 使用 48 | 49 | 首先导入 50 | 51 | ```swift 52 | import UIAdapter 53 | ``` 54 | 55 | 下面是一些简单示例. 支持所有设备和模拟器: 56 | 57 | ### Zoom 58 | 59 | 60 | AutoLayout (SnapKit): 61 | 62 | ```swift 63 | private func setupLayout() { 64 | cardView.snp.makeConstraints { (make) in 65 | make.top.equalTo(16.zoom()) 66 | make.left.right.equalToSuperview().inset(15.zoom()) 67 | make.bottom.equalTo(-26.zoom()) 68 | } 69 | 70 | lineView.snp.makeConstraints { (make) in 71 | make.left.right.equalToSuperview().inset(15.zoom()) 72 | make.top.equalTo(titleLabel.snp.bottom) 73 | make.height.equalTo(1) 74 | } 75 | 76 | titleLabel.snp.makeConstraints { (make) in 77 | make.top.equalToSuperview() 78 | make.left.equalTo(15.zoom()) 79 | make.height.equalTo(48.zoom()) 80 | } 81 | 82 | stateLabel.snp.makeConstraints { (make) in 83 | make.top.equalTo(lineView).offset(10.zoom()) 84 | make.left.equalTo(15.zoom()) 85 | make.height.equalTo(15.zoom()) 86 | } 87 | } 88 | ``` 89 | 90 | 属性设置 (Then): 91 | 92 | ```swift 93 | private lazy var cardView = UIView().then { 94 | $0.cornerRadius = 6.zoom() 95 | $0.backgroundColor = .white 96 | } 97 | 98 | private lazy var lineView = UIView().then { 99 | $0.backgroundColor = .hex("000000", alpha: 0.05) 100 | } 101 | 102 | private lazy var titleLabel = UILabel().then { 103 | $0.textColor = .black 104 | $0.font = .systemFont(ofSize: 20.zoom(), weight: .medium) 105 | } 106 | 107 | private lazy var stateLabel = UILabel().then { 108 | $0.textColor = .gray 109 | $0.font = .systemFont(ofSize: 12.zoom(), weight: .medium) 110 | } 111 | ``` 112 | 113 | Storyboard / Xib: 114 | 115 | ![约束](Resources/Storyboard%20Constraint.png) 116 | ![UILabel 字体大小](Resources/Storyboard%20Label%20Font.png) 117 | 118 | ### Inch 119 | 120 | 例子 121 | 122 | ```swift 123 | // default other screen numberOfLines = 0 124 | // 3.5 inches screen numberOfLines = 1 125 | // 4.0 inches screen numberOfLines = 2 126 | label.numberOfLines = 0.screen.inch(._3_5, is: 1).inch(._4_0, is: 2).value 127 | ``` 128 | 129 | 130 | ```swift 131 | // default other screen numberOfLines = 0 132 | // width 320 screen numberOfLines = 1 133 | // width 375 screen numberOfLines = 2 134 | label.numberOfLines = 0.screen.width(equalTo: 320, is: 1).width(equalTo: 375, is: 2).value 135 | ``` 136 | 137 | 138 | ```swift 139 | print("this is " + "default".screen 140 | .width(equalTo: 375, is: "宽度 等于 375") 141 | .width(lessThan: 414, is: "宽度 小于 414") 142 | .width(greaterThan: 414, is: "宽度 大于 414") 143 | .height(equalTo: 700, is: "高度 等于 375") 144 | .height(lessThan: 844, is: "高度 小于 844") 145 | .height(greaterThan: 844, is: "高度 大于 844") 146 | .inch(._4_7, is: "4.7 英寸") 147 | .inch(._5_8, is: "5.8 英寸") 148 | .inch(._6_5, is: "6.5 英寸") 149 | .level(.compact, is: "屏幕级别 紧凑屏 (4:3)") 150 | .level(.regular, is: "屏幕级别 常规屏 (16:9)") 151 | .level(.full, is: "屏幕级别 全面屏 (19.5:9)") 152 | .value 153 | ) 154 | ``` 155 | 156 | 157 | ## 截屏 158 | 159 | ![TikTok 1](Resources/Storyboard%20TikTok%20Demo1.jpg) 160 | 161 | ![TikTok 2](Resources/Storyboard%20TikTok%20Demo2.jpg) 162 | 163 | ## 贡献 164 | 165 | 如果您需要实现特定功能或遇到错误,请打开issue。 166 | 如果您自己扩展了UIAdapter的功能并希望其他人也使用它,请提交拉取请求。 167 | 168 | ## 协议 169 | 170 | UIAdapter 使用 MIT 协议. 有关更多信息,请参阅[LICENSE](LICENSE)文件. 171 | 172 | 173 | >### [相关文章 Inch](https://www.jianshu.com/p/d2c09cb65ef7) 174 | >### [相关文章 Auto](https://www.jianshu.com/p/e0e12206e0c7) 175 | >### [相关文章 Auto](https://www.jianshu.com/p/48c67d0c95b6) 176 | 177 | 178 | ----- 179 | 180 | > ## 欢迎入群交流 181 | ![QQ](https://github.com/lixiang1994/Resources/blob/master/QQClub/QQClub.JPG) 182 | -------------------------------------------------------------------------------- /Resources/Storyboard Constraint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Resources/Storyboard Constraint.png -------------------------------------------------------------------------------- /Resources/Storyboard Label Font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Resources/Storyboard Label Font.png -------------------------------------------------------------------------------- /Resources/Storyboard TikTok Demo1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Resources/Storyboard TikTok Demo1.jpg -------------------------------------------------------------------------------- /Resources/Storyboard TikTok Demo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixiang1994/UIAdapter/3b1a441b0c33128a003faacca438e91b27888a61/Resources/Storyboard TikTok Demo2.jpg -------------------------------------------------------------------------------- /Sources/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyTracking 6 | 7 | NSPrivacyAccessedAPITypes 8 | 9 | NSPrivacyTrackingDomains 10 | 11 | NSPrivacyCollectedDataTypes 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sources/Screen/UIAdapter.Screen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIAdapter.Screen.swift 3 | // ┌─┐ ┌───────┐ ┌───────┐ 4 | // │ │ │ ┌─────┘ │ ┌─────┘ 5 | // │ │ │ └─────┐ │ └─────┐ 6 | // │ │ │ ┌─────┘ │ ┌─────┘ 7 | // │ └─────┐│ └─────┐ │ └─────┐ 8 | // └───────┘└───────┘ └───────┘ 9 | // 10 | // Created by lee on 2018/1/22. 11 | // Copyright © 2018年 lee. All rights reserved. 12 | // 13 | 14 | // https://www.screensizes.app 15 | // https://useyourloaf.com/blog/iphone-14-screen-sizes/?continueFlag=d151fc49ec5161587c30f15faea0bee9 16 | 17 | import Foundation 18 | 19 | #if os(iOS) 20 | 21 | import UIKit 22 | 23 | public class UIAdapterScreenWrapper { 24 | 25 | let base: Screen 26 | 27 | public private(set) var value: Base 28 | 29 | init(_ value: Base) { 30 | self.base = .main 31 | self.value = value 32 | } 33 | 34 | init(_ value: Base, _ screen: UIScreen) { 35 | self.base = .init(screen) 36 | self.value = value 37 | } 38 | } 39 | 40 | public protocol UIAdapterScreenCompatible { 41 | associatedtype ScreenCompatibleType 42 | var screen: ScreenCompatibleType { get } 43 | 44 | func screen(_: UIScreen) -> ScreenCompatibleType 45 | } 46 | 47 | extension UIAdapterScreenCompatible { 48 | 49 | public var screen: UIAdapterScreenWrapper { 50 | get { return UIAdapterScreenWrapper(self) } 51 | } 52 | 53 | public func screen(_ screen: UIScreen) -> UIAdapterScreenWrapper { 54 | return UIAdapterScreenWrapper(self, screen) 55 | } 56 | } 57 | 58 | extension UIAdapterScreenWrapper { 59 | 60 | public typealias Screen = UIAdapter.Screen 61 | 62 | public func width(_ range: Range, is value: Base, zoomed: Base? = nil) -> Self { 63 | return width({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 64 | } 65 | public func width(_ range: ClosedRange, is value: Base, zoomed: Base? = nil) -> Self { 66 | return width({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 67 | } 68 | public func width(_ range: PartialRangeFrom, is value: Base, zoomed: Base? = nil) -> Self { 69 | return width({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 70 | } 71 | public func width(_ range: PartialRangeUpTo, is value: Base, zoomed: Base? = nil) -> Self { 72 | return width({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 73 | } 74 | public func width(_ range: PartialRangeThrough, is value: Base, zoomed: Base? = nil) -> Self { 75 | return width({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 76 | } 77 | 78 | public func width(greaterThan base: CGFloat, is value: Base, zoomed: Base? = nil) -> Self { 79 | return width({ $0 > base }, is: value, zoomed: zoomed ?? value) 80 | } 81 | public func width(lessThan base: CGFloat, is value: Base, zoomed: Base? = nil) -> Self { 82 | return width({ $0 < base }, is: value, zoomed: zoomed ?? value) 83 | } 84 | public func width(equalTo base: CGFloat, is value: Base, zoomed: Base? = nil) -> Self { 85 | return width({ $0 == base }, is: value, zoomed: zoomed ?? value) 86 | } 87 | private func width(_ matching: (CGFloat) -> Bool, is value: Base, zoomed: Base) -> Self { 88 | if matching(base.size.width) { 89 | self.value = base.isZoomedMode ? zoomed : value 90 | } 91 | return self 92 | } 93 | 94 | public func height(_ range: Range, is value: Base, zoomed: Base? = nil) -> Self { 95 | return height({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 96 | } 97 | public func height(_ range: ClosedRange, is value: Base, zoomed: Base? = nil) -> Self { 98 | return height({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 99 | } 100 | public func height(_ range: PartialRangeFrom, is value: Base, zoomed: Base? = nil) -> Self { 101 | return height({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 102 | } 103 | public func height(_ range: PartialRangeUpTo, is value: Base, zoomed: Base? = nil) -> Self { 104 | return height({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 105 | } 106 | public func height(_ range: PartialRangeThrough, is value: Base, zoomed: Base? = nil) -> Self { 107 | return height({ range.contains($0) }, is: value, zoomed: zoomed ?? value) 108 | } 109 | 110 | public func height(greaterThan base: CGFloat, is value: Base, zoomed: Base? = nil) -> Self { 111 | return height({ $0 > base }, is: value, zoomed: zoomed ?? value) 112 | } 113 | public func height(lessThan base: CGFloat, is value: Base, zoomed: Base? = nil) -> Self { 114 | return height({ $0 < base }, is: value, zoomed: zoomed ?? value) 115 | } 116 | public func height(equalTo base: CGFloat, is value: Base, zoomed: Base? = nil) -> Self { 117 | return height({ $0 == base }, is: value, zoomed: zoomed ?? value) 118 | } 119 | private func height(_ matching: (CGFloat) -> Bool, is value: Base, zoomed: Base) -> Self { 120 | if matching(base.size.height) { 121 | self.value = base.isZoomedMode ? zoomed : value 122 | } 123 | return self 124 | } 125 | 126 | public func inch(_ range: Range, is value: Base, zoomed: Base? = nil) -> Self { 127 | return inch({ range.contains($0.rawValue) }, is: value, zoomed: zoomed ?? value) 128 | } 129 | public func inch(_ range: ClosedRange, is value: Base, zoomed: Base? = nil) -> Self { 130 | return inch({ range.contains($0.rawValue) }, is: value, zoomed: zoomed ?? value) 131 | } 132 | public func inch(_ range: PartialRangeFrom, is value: Base, zoomed: Base? = nil) -> Self { 133 | return inch({ range.contains($0.rawValue) }, is: value, zoomed: zoomed ?? value) 134 | } 135 | public func inch(_ range: PartialRangeUpTo, is value: Base, zoomed: Base? = nil) -> Self { 136 | return inch({ range.contains($0.rawValue) }, is: value, zoomed: zoomed ?? value) 137 | } 138 | public func inch(_ range: PartialRangeThrough, is value: Base, zoomed: Base? = nil) -> Self { 139 | return inch({ range.contains($0.rawValue) }, is: value, zoomed: zoomed ?? value) 140 | } 141 | private func inch(_ matching: (Screen.Inch) -> Bool, is value: Base, zoomed: Base) -> Self { 142 | if matching(base.inch) { 143 | self.value = base.isZoomedMode ? zoomed : value 144 | } 145 | return self 146 | } 147 | 148 | public func inch(_ types: Screen.Inch..., is value: Base, zoomed: Base? = nil) -> Self { 149 | return inch(types, is: value, zoomed: zoomed ?? value) 150 | } 151 | public func inch(_ types: [Screen.Inch], is value: Base, zoomed: Base? = nil) -> Self { 152 | for type in types where base.inch == type { 153 | self.value = base.isZoomedMode ? zoomed ?? value : value 154 | } 155 | return self 156 | } 157 | 158 | public func level(_ types: Screen.Level..., is value: Base, zoomed: Base? = nil) -> Self { 159 | return level(types, is: value, zoomed: zoomed ?? value) 160 | } 161 | public func level(_ types: [Screen.Level], is value: Base, zoomed: Base? = nil) -> Self { 162 | for type in types where base.level == type { 163 | self.value = base.isZoomedMode ? zoomed ?? value : value 164 | } 165 | return self 166 | } 167 | } 168 | 169 | extension UIAdapter { 170 | 171 | public class Screen { 172 | 173 | let base: UIScreen 174 | 175 | init(_ base: UIScreen) { 176 | self.base = base 177 | } 178 | 179 | public var size: CGSize { 180 | base.bounds.size 181 | } 182 | public var nativeSize: CGSize { 183 | base.nativeBounds.size 184 | } 185 | public var scale: CGFloat { 186 | base.scale 187 | } 188 | public var nativeScale: CGFloat { 189 | base.nativeScale 190 | } 191 | 192 | /// 是否为显示缩放模式 193 | public var isZoomedMode: Bool { 194 | guard !UIDevice.iPhonePlus else { return size.width == 375 } 195 | guard !UIDevice.iPhoneMini else { return size.width == 320 } 196 | return scale != nativeScale 197 | } 198 | 199 | /// 真实宽高比 例如: iPhone 16 Pro (201:437) 200 | public var aspectRatio: String { 201 | if 202 | let cache = _aspectRatio, 203 | cache.0 == nativeSize { 204 | return cache.1 205 | 206 | } else { 207 | let result = base.aspectRatio 208 | _aspectRatio = (nativeSize, result) 209 | return result 210 | } 211 | } 212 | private var _aspectRatio: (CGSize, String)? 213 | 214 | /// 标准宽高比 例如: iPhone 16 Pro (9:19.5) 215 | public var standardAspectRatio: String { 216 | if 217 | let cache = _standardAspectRatio, 218 | cache.0 == nativeSize { 219 | return cache.1 220 | 221 | } else { 222 | let result = base.standardAspectRatio 223 | _standardAspectRatio = (nativeSize, result) 224 | return result 225 | } 226 | } 227 | private var _standardAspectRatio: (CGSize, String)? 228 | } 229 | } 230 | 231 | extension UIAdapter.Screen { 232 | 233 | /// 当前主屏幕 234 | public static let main = UIAdapter.Screen(.main) 235 | } 236 | 237 | extension UIAdapter.Screen { 238 | 239 | public enum Inch: Double { 240 | case unknown = -1 241 | case _3_5 = 3.5 242 | case _4_0 = 4.0 243 | case _4_7 = 4.7 244 | case _5_4 = 5.4 245 | case _5_5 = 5.5 246 | case _5_8 = 5.8 247 | case _6_1 = 6.1 248 | case _6_3 = 6.3 249 | case _6_5 = 6.5 250 | case _6_7 = 6.7 251 | case _6_9 = 6.9 252 | } 253 | 254 | public var inch: Inch { 255 | switch (nativeSize.width / scale, nativeSize.height / scale, scale) { 256 | case (320, 480, 2): 257 | return ._3_5 258 | 259 | case (320, 568, 2): 260 | return ._4_0 261 | 262 | case (375, 667, 2): 263 | return ._4_7 264 | 265 | case (360, 780, 3) where UIDevice.iPhoneMini, (375, 812, 3) where UIDevice.iPhoneMini: 266 | return ._5_4 267 | 268 | case (360, 640, 3) where UIDevice.iPhonePlus, (414, 736, 3) where UIDevice.iPhonePlus: 269 | return ._5_5 270 | 271 | case (375, 812, 3): 272 | return ._5_8 273 | 274 | case (414, 896, 2), (390, 844, 3), (393, 852, 3): 275 | return ._6_1 276 | 277 | case (402, 874, 3): 278 | return ._6_3 279 | 280 | case (414, 896, 3): 281 | return ._6_5 282 | 283 | case (428, 926, 3), (430, 932, 3): 284 | return ._6_7 285 | 286 | case (440, 956, 3): 287 | return ._6_9 288 | 289 | default: 290 | return .unknown 291 | } 292 | } 293 | 294 | public enum Level: Int { 295 | case unknown = -1 296 | /// 3: 2 297 | case compact 298 | /// 16: 9 299 | case regular 300 | /// 19.5: 9 301 | case full 302 | 303 | public var isCompact: Bool { 304 | self == .compact 305 | } 306 | 307 | public var isRegular: Bool { 308 | self == .regular 309 | } 310 | 311 | public var isFull: Bool { 312 | self == .full 313 | } 314 | } 315 | 316 | public var level: Level { 317 | switch standardAspectRatio { 318 | case "3:4", "4:3": 319 | return .compact 320 | 321 | case "9:16", "16:9": 322 | return .regular 323 | 324 | case "9:19.5", "19.5:9": 325 | return .full 326 | 327 | default: 328 | return .unknown 329 | } 330 | } 331 | } 332 | 333 | extension Int: UIAdapterScreenCompatible {} 334 | extension Bool: UIAdapterScreenCompatible {} 335 | extension Float: UIAdapterScreenCompatible {} 336 | extension Double: UIAdapterScreenCompatible {} 337 | extension String: UIAdapterScreenCompatible {} 338 | extension CGRect: UIAdapterScreenCompatible {} 339 | extension CGSize: UIAdapterScreenCompatible {} 340 | extension CGFloat: UIAdapterScreenCompatible {} 341 | extension CGPoint: UIAdapterScreenCompatible {} 342 | extension UIImage: UIAdapterScreenCompatible {} 343 | extension UIColor: UIAdapterScreenCompatible {} 344 | extension UIFont: UIAdapterScreenCompatible {} 345 | extension UIEdgeInsets: UIAdapterScreenCompatible {} 346 | 347 | 348 | fileprivate extension UIDevice { 349 | 350 | /// 是否使用了降采样 351 | static var isUsingDownsampling: Bool { 352 | return iPhoneMini || iPhonePlus 353 | } 354 | 355 | static var iPhoneMini: Bool { 356 | let temp = ["iPhone13,1", "iPhone14,4"] 357 | 358 | switch identifier { 359 | case "iPhone13,1", "iPhone14,4": 360 | return true 361 | 362 | case "i386", "x86_64", "arm64": 363 | return temp.contains(ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "") 364 | 365 | default: 366 | return false 367 | } 368 | } 369 | 370 | static var iPhonePlus: Bool { 371 | let temp = [ 372 | "iPhone7,1", 373 | "iPhone8,2", 374 | "iPhone9,2", 375 | "iPhone9,4", 376 | "iPhone10,2", 377 | "iPhone10,5" 378 | ] 379 | 380 | switch identifier { 381 | case 382 | "iPhone7,1", 383 | "iPhone8,2", 384 | "iPhone9,2", 385 | "iPhone9,4", 386 | "iPhone10,2", 387 | "iPhone10,5": 388 | return true 389 | 390 | case "i386", "x86_64", "arm64": 391 | return temp.contains(ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "") 392 | 393 | default: 394 | return false 395 | } 396 | } 397 | 398 | private static let identifier: String = { 399 | var systemInfo = utsname() 400 | uname(&systemInfo) 401 | let mirror = Mirror(reflecting: systemInfo.machine) 402 | 403 | let identifier = mirror.children.reduce("") { identifier, element in 404 | guard let value = element.value as? Int8, value != 0 else { return identifier } 405 | return identifier + String(UnicodeScalar(UInt8(value))) 406 | } 407 | return identifier 408 | } () 409 | } 410 | 411 | extension UIScreen { 412 | 413 | /// 真实宽高比 例如: iPhone 16 Pro (201:437) 414 | var aspectRatio: String { 415 | // 计算宽高比 416 | let (ratioWidth, ratioHeight) = calculateAspectRatio( 417 | width: nativeBounds.width, 418 | height: nativeBounds.height 419 | ) 420 | return "\(ratioWidth):\(ratioHeight)" 421 | } 422 | 423 | /// 标准宽高比 例如: iPhone 16 Pro (9:19.5) 424 | var standardAspectRatio: String { 425 | // 获取近似的标准比例 426 | return getStandardAspectRatio( 427 | width: nativeBounds.width, 428 | height: nativeBounds.height 429 | ) 430 | } 431 | 432 | private func calculateAspectRatio(width: CGFloat, height: CGFloat) -> (Int, Int) { 433 | // 计算最大公约数(欧几里得算法) 434 | func gcd(_ a: Int, _ b: Int) -> Int { 435 | var a = a 436 | var b = b 437 | while b != 0 { 438 | let temp = b 439 | b = a % b 440 | a = temp 441 | } 442 | return a 443 | } 444 | 445 | let precision: CGFloat = 1000 // 精度倍数 446 | let widthInt = Int(width * precision) 447 | let heightInt = Int(height * precision) 448 | 449 | let gcdValue = gcd(widthInt, heightInt) 450 | 451 | let ratioWidth = widthInt / gcdValue 452 | let ratioHeight = heightInt / gcdValue 453 | 454 | return (ratioWidth, ratioHeight) 455 | } 456 | 457 | private func getStandardAspectRatio(width: CGFloat, height: CGFloat) -> String { 458 | let aspectRatio = width / height 459 | 460 | // 常见的屏幕比例 461 | let commonRatios: [(ratio: CGFloat, description: String)] = [ 462 | (16.0/9.0, "16:9"), 463 | (9.0/16.0, "9:16"), 464 | (4.0/3.0, "4:3"), 465 | (3.0/4.0, "3:4"), 466 | (19.5/9.0, "19.5:9"), 467 | (9.0/19.5, "9:19.5"), 468 | (2.0/1.0, "2:1"), 469 | (1.0/2.0, "1:2"), 470 | (1.0/1.0, "1:1") 471 | ] 472 | 473 | var closestRatio = commonRatios[0] 474 | var smallestDifference = abs(aspectRatio - closestRatio.ratio) 475 | 476 | for ratio in commonRatios { 477 | let difference = abs(aspectRatio - ratio.ratio) 478 | if difference < smallestDifference { 479 | smallestDifference = difference 480 | closestRatio = ratio 481 | } 482 | } 483 | 484 | return closestRatio.description 485 | } 486 | } 487 | 488 | #endif 489 | -------------------------------------------------------------------------------- /Sources/UIAdapter.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIAdapter.h 3 | // UIAdapter 4 | // 5 | // Created by 李响 on 2021/10/11. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for UIAdapter. 11 | FOUNDATION_EXPORT double UIAdapterVersionNumber; 12 | 13 | //! Project version string for UIAdapter. 14 | FOUNDATION_EXPORT const unsigned char UIAdapterVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sources/Zoom/UIAdapter.Zoom.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIAdapter.Zoom.swift 3 | // ┌─┐ ┌───────┐ ┌───────┐ 4 | // │ │ │ ┌─────┘ │ ┌─────┘ 5 | // │ │ │ └─────┐ │ └─────┐ 6 | // │ │ │ ┌─────┘ │ ┌─────┘ 7 | // │ └─────┐│ └─────┐ │ └─────┐ 8 | // └───────┘└───────┘ └───────┘ 9 | // 10 | // Created by lee on 2018/11/2. 11 | // Copyright © 2018年 lee. All rights reserved. 12 | // 13 | 14 | #if canImport(Foundation) 15 | 16 | import Foundation 17 | 18 | #if os(iOS) 19 | 20 | import UIKit 21 | 22 | public enum UIAdapter { 23 | 24 | public enum Zoom { 25 | 26 | /// 设置转换闭包 27 | /// 28 | /// - Parameter conversion: 转换闭包 29 | public static func set(conversion: @escaping ((Double) -> Double)) { 30 | conversionClosure = conversion 31 | } 32 | 33 | /// 转换 用于数值的等比例计算 如需自定义可重新设置 34 | static var conversionClosure: ((Double) -> Double) = { (origin) in 35 | guard UIDevice.current.userInterfaceIdiom == .phone else { 36 | return origin 37 | } 38 | 39 | let base = 375.0 40 | let screenWidth = Double(UIScreen.main.bounds.width) 41 | let screenHeight = Double(UIScreen.main.bounds.height) 42 | let width = min(screenWidth, screenHeight) 43 | let result = origin * (width / base) 44 | let scale = Double(UIScreen.main.scale) 45 | return (result * scale).rounded(.up) / scale 46 | } 47 | } 48 | } 49 | 50 | extension UIAdapter.Zoom { 51 | 52 | static func conversion(_ value: Double) -> Double { 53 | return conversionClosure(value) 54 | } 55 | } 56 | 57 | public protocol UIAdapterZoomCalculationable { 58 | 59 | /// 缩放计算 60 | /// 61 | /// - Returns: 结果 62 | func zoom() -> Self 63 | } 64 | 65 | extension Double: UIAdapterZoomCalculationable { 66 | 67 | public func zoom() -> Double { 68 | return UIAdapter.Zoom.conversion(self) 69 | } 70 | } 71 | 72 | extension BinaryInteger { 73 | 74 | public func zoom() -> Double { 75 | let temp = Double("\(self)") ?? 0 76 | return temp.zoom() 77 | } 78 | public func zoom() -> T where T : BinaryInteger { 79 | let temp = Double("\(self)") ?? 0 80 | return temp.zoom() 81 | } 82 | public func zoom() -> T where T : BinaryFloatingPoint { 83 | let temp = Double("\(self)") ?? 0 84 | return temp.zoom() 85 | } 86 | } 87 | 88 | extension BinaryFloatingPoint { 89 | 90 | public func zoom() -> Double { 91 | let temp = Double("\(self)") ?? 0 92 | return temp.zoom() 93 | } 94 | public func zoom() -> T where T : BinaryInteger { 95 | let temp = Double("\(self)") ?? 0 96 | return T(temp.zoom()) 97 | } 98 | public func zoom() -> T where T : BinaryFloatingPoint { 99 | let temp = Double("\(self)") ?? 0 100 | return T(temp.zoom()) 101 | } 102 | } 103 | 104 | extension CGPoint: UIAdapterZoomCalculationable { 105 | 106 | public func zoom() -> CGPoint { 107 | return CGPoint(x: x.zoom(), y: y.zoom()) 108 | } 109 | } 110 | 111 | extension CGSize: UIAdapterZoomCalculationable { 112 | 113 | public func zoom() -> CGSize { 114 | return CGSize(width: width.zoom(), height: height.zoom()) 115 | } 116 | } 117 | 118 | extension CGRect: UIAdapterZoomCalculationable { 119 | 120 | public func zoom() -> CGRect { 121 | return CGRect(origin: origin.zoom(), size: size.zoom()) 122 | } 123 | } 124 | 125 | extension CGVector: UIAdapterZoomCalculationable { 126 | 127 | public func zoom() -> CGVector { 128 | return CGVector(dx: dx.zoom(), dy: dy.zoom()) 129 | } 130 | } 131 | 132 | extension UIOffset: UIAdapterZoomCalculationable { 133 | 134 | public func zoom() -> UIOffset { 135 | return UIOffset(horizontal: horizontal.zoom(), vertical: vertical.zoom()) 136 | } 137 | } 138 | 139 | extension UIEdgeInsets: UIAdapterZoomCalculationable { 140 | 141 | public func zoom() -> UIEdgeInsets { 142 | return UIEdgeInsets( 143 | top: top.zoom(), 144 | left: left.zoom(), 145 | bottom: bottom.zoom(), 146 | right: right.zoom() 147 | ) 148 | } 149 | } 150 | 151 | 152 | extension NSLayoutConstraint { 153 | 154 | @IBInspectable private var zoomConstant: Bool { 155 | get { return false } 156 | set { 157 | guard newValue else { return } 158 | 159 | constant = constant.zoom() 160 | } 161 | } 162 | } 163 | 164 | extension UIView { 165 | 166 | @IBInspectable private var zoomCornerRadius: CGFloat { 167 | get { return layer.cornerRadius } 168 | set { 169 | let value: CGFloat = newValue.zoom() 170 | layer.masksToBounds = true 171 | layer.cornerRadius = abs(CGFloat(Int(value * 100)) / 100) 172 | } 173 | } 174 | } 175 | 176 | extension UILabel { 177 | 178 | @IBInspectable private var zoomFont: Bool { 179 | get { return false } 180 | set { 181 | guard newValue else { return } 182 | guard let text = attributedText?.mutableCopy() as? NSMutableAttributedString else { 183 | return 184 | } 185 | 186 | font = font.withSize(font.pointSize.zoom()) 187 | attributedText = text.reset(font: { $0.zoom() }) 188 | } 189 | } 190 | 191 | @IBInspectable private var zoomLine: Bool { 192 | get { return false } 193 | set { 194 | guard newValue else { return } 195 | guard let text = attributedText else { return } 196 | 197 | attributedText = text.reset(line: { $0.zoom() }) 198 | } 199 | } 200 | 201 | @IBInspectable private var zoomShadowOffset: Bool { 202 | get { return false } 203 | set { 204 | guard newValue else { return } 205 | 206 | shadowOffset = shadowOffset.zoom() 207 | } 208 | } 209 | } 210 | 211 | extension UITextView { 212 | 213 | @IBInspectable private var zoomFont: Bool { 214 | get { return false } 215 | set { 216 | guard newValue else { return } 217 | guard let font = font else { return } 218 | 219 | self.font = font.withSize(font.pointSize.zoom()) 220 | } 221 | } 222 | } 223 | 224 | extension UITextField { 225 | 226 | @IBInspectable private var zoomFont: Bool { 227 | get { return false } 228 | set { 229 | guard newValue else { return } 230 | guard let font = font else { return } 231 | 232 | self.font = font.withSize(font.pointSize.zoom()) 233 | } 234 | } 235 | } 236 | 237 | extension UIImageView { 238 | 239 | @IBInspectable private var zoomImage: Bool { 240 | get { return false } 241 | set { 242 | guard newValue else { return } 243 | 244 | if let width = image?.size.width { 245 | image = image?.scaled(to: width.zoom()) 246 | } 247 | if let width = highlightedImage?.size.width { 248 | highlightedImage = highlightedImage?.scaled(to: width.zoom()) 249 | } 250 | } 251 | } 252 | } 253 | 254 | extension UIButton { 255 | 256 | @IBInspectable private var zoomTitle: Bool { 257 | get { return false } 258 | set { 259 | guard newValue else { return } 260 | 261 | let states: [UIControl.State] = [ 262 | .normal, 263 | .highlighted, 264 | .selected, 265 | .disabled 266 | ] 267 | 268 | if 269 | let _ = title(for: state), 270 | let label = titleLabel, 271 | let font = label.font { 272 | label.font = font.withSize(font.pointSize.zoom()) 273 | } 274 | 275 | let titles = states.enumerated().compactMap { 276 | (i, state) -> (Int, NSAttributedString)? in 277 | guard let t = attributedTitle(for: state) else { return nil } 278 | return (i, t) 279 | } 280 | titles.filtered(duplication: { $0.1 }).forEach { 281 | setAttributedTitle( 282 | $0.1.reset(font: { $0.zoom() }), 283 | for: states[$0.0] 284 | ) 285 | } 286 | } 287 | } 288 | 289 | @IBInspectable private var zoomImage: Bool { 290 | get { return false } 291 | set { 292 | guard newValue else { return } 293 | 294 | let states: [UIControl.State] = [ 295 | .normal, 296 | .highlighted, 297 | .selected, 298 | .disabled 299 | ] 300 | 301 | let images = states.enumerated().compactMap { 302 | (i, state) -> (Int, UIImage)? in 303 | guard let v = image(for: state) else { return nil } 304 | return (i, v) 305 | } 306 | images.filtered(duplication: { $0.1 }).forEach { 307 | setImage( 308 | $0.1.scaled(to: $0.1.size.width.zoom()), 309 | for: states[$0.0] 310 | ) 311 | } 312 | 313 | let backgrounds = states.enumerated().compactMap { 314 | (i, state) -> (Int, UIImage)? in 315 | guard let v = backgroundImage(for: state) else { return nil } 316 | return (i, v) 317 | } 318 | backgrounds.filtered(duplication: { $0.1 }).forEach { 319 | setBackgroundImage( 320 | $0.1.scaled(to: $0.1.size.width.zoom()), 321 | for: states[$0.0] 322 | ) 323 | } 324 | } 325 | } 326 | 327 | @IBInspectable private var zoomTitleInsets: Bool { 328 | get { return false } 329 | set { 330 | guard newValue else { return } 331 | 332 | titleEdgeInsets = titleEdgeInsets.zoom() 333 | } 334 | } 335 | 336 | @IBInspectable private var zoomImageInsets: Bool { 337 | get { return false } 338 | set { 339 | guard newValue else { return } 340 | 341 | imageEdgeInsets = imageEdgeInsets.zoom() 342 | } 343 | } 344 | 345 | @IBInspectable private var zoomContentInsets: Bool { 346 | get { return false } 347 | set { 348 | guard newValue else { return } 349 | 350 | contentEdgeInsets = contentEdgeInsets.zoom() 351 | } 352 | } 353 | } 354 | 355 | @available(iOS 9.0, *) 356 | extension UIStackView { 357 | 358 | @IBInspectable private var zoomSpacing: Bool { 359 | get { return false } 360 | set { 361 | guard newValue else { return } 362 | 363 | spacing = spacing.zoom() 364 | } 365 | } 366 | } 367 | 368 | fileprivate extension NSAttributedString { 369 | 370 | func reset(font size: (CGFloat) -> CGFloat) -> NSAttributedString { 371 | let string = NSMutableAttributedString(attributedString: self) 372 | enumerateAttributes( 373 | in: NSRange(location: 0, length: length), 374 | options: .longestEffectiveRangeNotRequired 375 | ) { (attributes, range, stop) in 376 | var temp = attributes 377 | if let font = attributes[.font] as? UIFont { 378 | temp[.font] = font.withSize(size(font.pointSize)) 379 | } 380 | string.setAttributes(temp, range: range) 381 | } 382 | return string 383 | } 384 | 385 | func reset(line spacing: (CGFloat) -> CGFloat) -> NSAttributedString { 386 | let string = NSMutableAttributedString(attributedString: self) 387 | enumerateAttributes( 388 | in: NSRange(location: 0, length: length), 389 | options: .longestEffectiveRangeNotRequired 390 | ) { (attributes, range, stop) in 391 | var temp = attributes 392 | if let paragraph = attributes[.paragraphStyle] as? NSMutableParagraphStyle { 393 | paragraph.lineSpacing = spacing(paragraph.lineSpacing) 394 | temp[.paragraphStyle] = paragraph 395 | } 396 | string.setAttributes(temp, range: range) 397 | } 398 | return string 399 | } 400 | } 401 | 402 | fileprivate extension UIImage { 403 | 404 | func scaled(to width: CGFloat, opaque: Bool = false) -> UIImage? { 405 | guard self.size.width > 0 else { 406 | return nil 407 | } 408 | 409 | let scale = width / self.size.width 410 | let size = CGSize(width: width, height: self.size.height * scale) 411 | UIGraphicsBeginImageContextWithOptions(size, false, 0) 412 | draw(in: CGRect(origin: .zero, size: size)) 413 | let new = UIGraphicsGetImageFromCurrentImageContext() 414 | UIGraphicsEndImageContext() 415 | return new 416 | } 417 | } 418 | 419 | fileprivate extension Array { 420 | 421 | func filtered(duplication closure: (Element) throws -> E) rethrows -> [Element] { 422 | return try reduce(into: [Element]()) { (result, e) in 423 | let contains = try result.contains { try closure($0) == closure(e) } 424 | result += contains ? [] : [e] 425 | } 426 | } 427 | } 428 | 429 | public extension Double { 430 | 431 | func rounded(_ decimalPlaces: Int) -> Double { 432 | let divisor = pow(10.0, Double(max(0, decimalPlaces))) 433 | return (self * divisor).rounded() / divisor 434 | } 435 | } 436 | 437 | public extension BinaryFloatingPoint { 438 | 439 | func rounded(_ decimalPlaces: Int) -> Double { 440 | let temp = Double("\(self)") ?? 0 441 | return temp.rounded(decimalPlaces) 442 | } 443 | 444 | func rounded(_ decimalPlaces: Int) -> T where T: BinaryFloatingPoint { 445 | let temp = Double("\(self)") ?? 0 446 | return T(temp.rounded(decimalPlaces)) 447 | } 448 | } 449 | 450 | public extension CGPoint { 451 | 452 | func rounded(_ decimalPlaces: Int) -> CGPoint { 453 | return CGPoint(x: x.rounded(decimalPlaces), y: y.rounded(decimalPlaces)) 454 | } 455 | } 456 | 457 | public extension CGSize { 458 | 459 | func rounded(_ decimalPlaces: Int) -> CGSize { 460 | return CGSize(width: width.rounded(decimalPlaces), height: height.rounded(decimalPlaces)) 461 | } 462 | } 463 | 464 | public extension CGRect { 465 | 466 | func rounded(_ decimalPlaces: Int) -> CGRect { 467 | return CGRect(origin: origin.rounded(decimalPlaces), size: size.rounded(decimalPlaces)) 468 | } 469 | } 470 | 471 | public extension UIEdgeInsets { 472 | 473 | func rounded(_ decimalPlaces: Int) -> UIEdgeInsets { 474 | return UIEdgeInsets( 475 | top: top.rounded(decimalPlaces), 476 | left: left.rounded(decimalPlaces), 477 | bottom: bottom.rounded(decimalPlaces), 478 | right: right.rounded(decimalPlaces) 479 | ) 480 | } 481 | } 482 | 483 | #endif 484 | 485 | #endif 486 | 487 | -------------------------------------------------------------------------------- /Tests/UIAdapterTests/UIAdapterTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import UIAdapter 3 | 4 | final class UIAdapterTests: XCTestCase { 5 | func testExample() throws { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | XCTAssertEqual(UIAdapter().text, "Hello, World!") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIAdapter.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "UIAdapter" 4 | s.version = "1.4.0" 5 | s.summary = "iOS屏幕适配工具" 6 | 7 | s.homepage = "https://github.com/lixiang1994/UIAdapter" 8 | 9 | s.license = { :type => "MIT", :file => "LICENSE" } 10 | 11 | s.author = { "LEE" => "18611401994@163.com" } 12 | 13 | s.platform = :ios, "9.0" 14 | 15 | s.source = { :git => "https://github.com/lixiang1994/UIAdapter.git", :tag => s.version } 16 | 17 | s.source_files = "Sources/**/*.swift" 18 | 19 | s.requires_arc = true 20 | 21 | s.swift_version = '5.5' 22 | 23 | s.cocoapods_version = '>= 1.4.0' 24 | 25 | s.subspec 'Privacy' do |ss| 26 | ss.resource_bundles = { 27 | s.name => 'Sources/PrivacyInfo.xcprivacy' 28 | } 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /UIAdapter.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9BBE2D392BC565DE001F9632 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 9BBE2D382BC565DE001F9632 /* PrivacyInfo.xcprivacy */; }; 11 | 9BEB034A27140DFD003CC3DD /* UIAdapter.Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEB034627140DFD003CC3DD /* UIAdapter.Zoom.swift */; }; 12 | 9BEB034B27140DFD003CC3DD /* UIAdapter.Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEB034827140DFD003CC3DD /* UIAdapter.Screen.swift */; }; 13 | 9BEB034C27140ED7003CC3DD /* UIAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BEB034427140DFD003CC3DD /* UIAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | 9BBE2D382BC565DE001F9632 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 18 | 9BEB03372713EEBA003CC3DD /* UIAdapter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UIAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 9BEB034427140DFD003CC3DD /* UIAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAdapter.h; sourceTree = ""; }; 20 | 9BEB034627140DFD003CC3DD /* UIAdapter.Zoom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAdapter.Zoom.swift; sourceTree = ""; }; 21 | 9BEB034827140DFD003CC3DD /* UIAdapter.Screen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAdapter.Screen.swift; sourceTree = ""; }; 22 | /* End PBXFileReference section */ 23 | 24 | /* Begin PBXFrameworksBuildPhase section */ 25 | 9BEB03342713EEBA003CC3DD /* Frameworks */ = { 26 | isa = PBXFrameworksBuildPhase; 27 | buildActionMask = 2147483647; 28 | files = ( 29 | ); 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXFrameworksBuildPhase section */ 33 | 34 | /* Begin PBXGroup section */ 35 | 9BEB032D2713EEBA003CC3DD = { 36 | isa = PBXGroup; 37 | children = ( 38 | 9BEB03392713EEBA003CC3DD /* Sources */, 39 | 9BEB03382713EEBA003CC3DD /* Products */, 40 | ); 41 | sourceTree = ""; 42 | }; 43 | 9BEB03382713EEBA003CC3DD /* Products */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 9BEB03372713EEBA003CC3DD /* UIAdapter.framework */, 47 | ); 48 | name = Products; 49 | sourceTree = ""; 50 | }; 51 | 9BEB03392713EEBA003CC3DD /* Sources */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 9BEB034427140DFD003CC3DD /* UIAdapter.h */, 55 | 9BBE2D382BC565DE001F9632 /* PrivacyInfo.xcprivacy */, 56 | 9BEB034527140DFD003CC3DD /* Zoom */, 57 | 9BEB034727140DFD003CC3DD /* Screen */, 58 | ); 59 | path = Sources; 60 | sourceTree = ""; 61 | }; 62 | 9BEB034527140DFD003CC3DD /* Zoom */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 9BEB034627140DFD003CC3DD /* UIAdapter.Zoom.swift */, 66 | ); 67 | path = Zoom; 68 | sourceTree = ""; 69 | }; 70 | 9BEB034727140DFD003CC3DD /* Screen */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 9BEB034827140DFD003CC3DD /* UIAdapter.Screen.swift */, 74 | ); 75 | path = Screen; 76 | sourceTree = ""; 77 | }; 78 | /* End PBXGroup section */ 79 | 80 | /* Begin PBXHeadersBuildPhase section */ 81 | 9BEB03322713EEBA003CC3DD /* Headers */ = { 82 | isa = PBXHeadersBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | 9BEB034C27140ED7003CC3DD /* UIAdapter.h in Headers */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXHeadersBuildPhase section */ 90 | 91 | /* Begin PBXNativeTarget section */ 92 | 9BEB03362713EEBA003CC3DD /* UIAdapter */ = { 93 | isa = PBXNativeTarget; 94 | buildConfigurationList = 9BEB033E2713EEBA003CC3DD /* Build configuration list for PBXNativeTarget "UIAdapter" */; 95 | buildPhases = ( 96 | 9BEB03322713EEBA003CC3DD /* Headers */, 97 | 9BEB03332713EEBA003CC3DD /* Sources */, 98 | 9BEB03342713EEBA003CC3DD /* Frameworks */, 99 | 9BEB03352713EEBA003CC3DD /* Resources */, 100 | ); 101 | buildRules = ( 102 | ); 103 | dependencies = ( 104 | ); 105 | name = UIAdapter; 106 | productName = UIAdapter; 107 | productReference = 9BEB03372713EEBA003CC3DD /* UIAdapter.framework */; 108 | productType = "com.apple.product-type.framework"; 109 | }; 110 | /* End PBXNativeTarget section */ 111 | 112 | /* Begin PBXProject section */ 113 | 9BEB032E2713EEBA003CC3DD /* Project object */ = { 114 | isa = PBXProject; 115 | attributes = { 116 | BuildIndependentTargetsInParallel = 1; 117 | LastUpgradeCheck = 1300; 118 | TargetAttributes = { 119 | 9BEB03362713EEBA003CC3DD = { 120 | CreatedOnToolsVersion = 13.0; 121 | }; 122 | }; 123 | }; 124 | buildConfigurationList = 9BEB03312713EEBA003CC3DD /* Build configuration list for PBXProject "UIAdapter" */; 125 | compatibilityVersion = "Xcode 13.0"; 126 | developmentRegion = en; 127 | hasScannedForEncodings = 0; 128 | knownRegions = ( 129 | en, 130 | Base, 131 | ); 132 | mainGroup = 9BEB032D2713EEBA003CC3DD; 133 | productRefGroup = 9BEB03382713EEBA003CC3DD /* Products */; 134 | projectDirPath = ""; 135 | projectRoot = ""; 136 | targets = ( 137 | 9BEB03362713EEBA003CC3DD /* UIAdapter */, 138 | ); 139 | }; 140 | /* End PBXProject section */ 141 | 142 | /* Begin PBXResourcesBuildPhase section */ 143 | 9BEB03352713EEBA003CC3DD /* Resources */ = { 144 | isa = PBXResourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 9BBE2D392BC565DE001F9632 /* PrivacyInfo.xcprivacy in Resources */, 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXResourcesBuildPhase section */ 152 | 153 | /* Begin PBXSourcesBuildPhase section */ 154 | 9BEB03332713EEBA003CC3DD /* Sources */ = { 155 | isa = PBXSourcesBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | 9BEB034B27140DFD003CC3DD /* UIAdapter.Screen.swift in Sources */, 159 | 9BEB034A27140DFD003CC3DD /* UIAdapter.Zoom.swift in Sources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXSourcesBuildPhase section */ 164 | 165 | /* Begin XCBuildConfiguration section */ 166 | 9BEB033C2713EEBA003CC3DD /* Debug */ = { 167 | isa = XCBuildConfiguration; 168 | buildSettings = { 169 | ALWAYS_SEARCH_USER_PATHS = NO; 170 | CLANG_ANALYZER_NONNULL = YES; 171 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 172 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 173 | CLANG_CXX_LIBRARY = "libc++"; 174 | CLANG_ENABLE_MODULES = YES; 175 | CLANG_ENABLE_OBJC_ARC = YES; 176 | CLANG_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 193 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 194 | CLANG_WARN_STRICT_PROTOTYPES = YES; 195 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 196 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 197 | CLANG_WARN_UNREACHABLE_CODE = YES; 198 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 199 | COPY_PHASE_STRIP = NO; 200 | CURRENT_PROJECT_VERSION = 1; 201 | DEBUG_INFORMATION_FORMAT = dwarf; 202 | ENABLE_STRICT_OBJC_MSGSEND = YES; 203 | ENABLE_TESTABILITY = YES; 204 | GCC_C_LANGUAGE_STANDARD = gnu11; 205 | GCC_DYNAMIC_NO_PIC = NO; 206 | GCC_NO_COMMON_BLOCKS = YES; 207 | GCC_OPTIMIZATION_LEVEL = 0; 208 | GCC_PREPROCESSOR_DEFINITIONS = ( 209 | "DEBUG=1", 210 | "$(inherited)", 211 | ); 212 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 213 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 214 | GCC_WARN_UNDECLARED_SELECTOR = YES; 215 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 216 | GCC_WARN_UNUSED_FUNCTION = YES; 217 | GCC_WARN_UNUSED_VARIABLE = YES; 218 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 219 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 220 | MTL_FAST_MATH = YES; 221 | ONLY_ACTIVE_ARCH = YES; 222 | SDKROOT = iphoneos; 223 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 224 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 225 | VERSIONING_SYSTEM = "apple-generic"; 226 | VERSION_INFO_PREFIX = ""; 227 | }; 228 | name = Debug; 229 | }; 230 | 9BEB033D2713EEBA003CC3DD /* Release */ = { 231 | isa = XCBuildConfiguration; 232 | buildSettings = { 233 | ALWAYS_SEARCH_USER_PATHS = NO; 234 | CLANG_ANALYZER_NONNULL = YES; 235 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 236 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 237 | CLANG_CXX_LIBRARY = "libc++"; 238 | CLANG_ENABLE_MODULES = YES; 239 | CLANG_ENABLE_OBJC_ARC = YES; 240 | CLANG_ENABLE_OBJC_WEAK = YES; 241 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 242 | CLANG_WARN_BOOL_CONVERSION = YES; 243 | CLANG_WARN_COMMA = YES; 244 | CLANG_WARN_CONSTANT_CONVERSION = YES; 245 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 246 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 247 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 248 | CLANG_WARN_EMPTY_BODY = YES; 249 | CLANG_WARN_ENUM_CONVERSION = YES; 250 | CLANG_WARN_INFINITE_RECURSION = YES; 251 | CLANG_WARN_INT_CONVERSION = YES; 252 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 253 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 254 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 255 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 256 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 261 | CLANG_WARN_UNREACHABLE_CODE = YES; 262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 263 | COPY_PHASE_STRIP = NO; 264 | CURRENT_PROJECT_VERSION = 1; 265 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 266 | ENABLE_NS_ASSERTIONS = NO; 267 | ENABLE_STRICT_OBJC_MSGSEND = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu11; 269 | GCC_NO_COMMON_BLOCKS = YES; 270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 272 | GCC_WARN_UNDECLARED_SELECTOR = YES; 273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 274 | GCC_WARN_UNUSED_FUNCTION = YES; 275 | GCC_WARN_UNUSED_VARIABLE = YES; 276 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 277 | MTL_ENABLE_DEBUG_INFO = NO; 278 | MTL_FAST_MATH = YES; 279 | SDKROOT = iphoneos; 280 | SWIFT_COMPILATION_MODE = wholemodule; 281 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 282 | VALIDATE_PRODUCT = YES; 283 | VERSIONING_SYSTEM = "apple-generic"; 284 | VERSION_INFO_PREFIX = ""; 285 | }; 286 | name = Release; 287 | }; 288 | 9BEB033F2713EEBA003CC3DD /* Debug */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | CODE_SIGN_STYLE = Automatic; 292 | CURRENT_PROJECT_VERSION = 1; 293 | DEFINES_MODULE = YES; 294 | DYLIB_COMPATIBILITY_VERSION = 1; 295 | DYLIB_CURRENT_VERSION = 1; 296 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 297 | GENERATE_INFOPLIST_FILE = YES; 298 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 299 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 300 | LD_RUNPATH_SEARCH_PATHS = ( 301 | "$(inherited)", 302 | "@executable_path/Frameworks", 303 | "@loader_path/Frameworks", 304 | ); 305 | MARKETING_VERSION = 1.0; 306 | PRODUCT_BUNDLE_IDENTIFIER = com.lee.UIAdapter; 307 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 308 | SKIP_INSTALL = YES; 309 | SWIFT_EMIT_LOC_STRINGS = YES; 310 | SWIFT_VERSION = 5.0; 311 | TARGETED_DEVICE_FAMILY = "1,2"; 312 | }; 313 | name = Debug; 314 | }; 315 | 9BEB03402713EEBA003CC3DD /* Release */ = { 316 | isa = XCBuildConfiguration; 317 | buildSettings = { 318 | CODE_SIGN_STYLE = Automatic; 319 | CURRENT_PROJECT_VERSION = 1; 320 | DEFINES_MODULE = YES; 321 | DYLIB_COMPATIBILITY_VERSION = 1; 322 | DYLIB_CURRENT_VERSION = 1; 323 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 324 | GENERATE_INFOPLIST_FILE = YES; 325 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 326 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 327 | LD_RUNPATH_SEARCH_PATHS = ( 328 | "$(inherited)", 329 | "@executable_path/Frameworks", 330 | "@loader_path/Frameworks", 331 | ); 332 | MARKETING_VERSION = 1.0; 333 | PRODUCT_BUNDLE_IDENTIFIER = com.lee.UIAdapter; 334 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 335 | SKIP_INSTALL = YES; 336 | SWIFT_EMIT_LOC_STRINGS = YES; 337 | SWIFT_VERSION = 5.0; 338 | TARGETED_DEVICE_FAMILY = "1,2"; 339 | }; 340 | name = Release; 341 | }; 342 | /* End XCBuildConfiguration section */ 343 | 344 | /* Begin XCConfigurationList section */ 345 | 9BEB03312713EEBA003CC3DD /* Build configuration list for PBXProject "UIAdapter" */ = { 346 | isa = XCConfigurationList; 347 | buildConfigurations = ( 348 | 9BEB033C2713EEBA003CC3DD /* Debug */, 349 | 9BEB033D2713EEBA003CC3DD /* Release */, 350 | ); 351 | defaultConfigurationIsVisible = 0; 352 | defaultConfigurationName = Release; 353 | }; 354 | 9BEB033E2713EEBA003CC3DD /* Build configuration list for PBXNativeTarget "UIAdapter" */ = { 355 | isa = XCConfigurationList; 356 | buildConfigurations = ( 357 | 9BEB033F2713EEBA003CC3DD /* Debug */, 358 | 9BEB03402713EEBA003CC3DD /* Release */, 359 | ); 360 | defaultConfigurationIsVisible = 0; 361 | defaultConfigurationName = Release; 362 | }; 363 | /* End XCConfigurationList section */ 364 | }; 365 | rootObject = 9BEB032E2713EEBA003CC3DD /* Project object */; 366 | } 367 | -------------------------------------------------------------------------------- /UIAdapter.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIAdapter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIAdapter.xcodeproj/xcshareddata/xcschemes/UIAdapter.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | --------------------------------------------------------------------------------