├── .DS_Store ├── QQConfiguration.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── QQConfiguration.xccheckout │ └── xcuserdata │ │ └── shinept.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── shinept.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── QQConfiguration.xcscheme │ └── xcschememanagement.plist ├── QQConfiguration ├── AppDelegate.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── LeftsideViewController.swift ├── MasterViewController.swift └── ViewController.swift ├── QQConfigurationGIF.gif ├── QQConfigurationTests ├── Info.plist └── QQConfigurationTests.swift └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinept/QQConfiguration/812b6b5ef0b05322701947f378c32c80673d6a32/.DS_Store -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CE19AB721ACE2CE300A221EC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE19AB711ACE2CE300A221EC /* AppDelegate.swift */; }; 11 | CE19AB741ACE2CE300A221EC /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE19AB731ACE2CE300A221EC /* ViewController.swift */; }; 12 | CE19AB771ACE2CE300A221EC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE19AB751ACE2CE300A221EC /* Main.storyboard */; }; 13 | CE19AB791ACE2CE300A221EC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE19AB781ACE2CE300A221EC /* Images.xcassets */; }; 14 | CE19AB7C1ACE2CE300A221EC /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19AB7A1ACE2CE300A221EC /* LaunchScreen.xib */; }; 15 | CE19AB881ACE2CE300A221EC /* QQConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE19AB871ACE2CE300A221EC /* QQConfigurationTests.swift */; }; 16 | CE19AB921ACE49B900A221EC /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE19AB911ACE49B900A221EC /* MasterViewController.swift */; }; 17 | CE19AB941ACE49C400A221EC /* LeftsideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE19AB931ACE49C400A221EC /* LeftsideViewController.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | CE19AB821ACE2CE300A221EC /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = CE19AB641ACE2CE300A221EC /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = CE19AB6B1ACE2CE300A221EC; 26 | remoteInfo = QQConfiguration; 27 | }; 28 | /* End PBXContainerItemProxy section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | CE19AB6C1ACE2CE300A221EC /* QQConfiguration.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QQConfiguration.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | CE19AB701ACE2CE300A221EC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | CE19AB711ACE2CE300A221EC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 34 | CE19AB731ACE2CE300A221EC /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 35 | CE19AB761ACE2CE300A221EC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 36 | CE19AB781ACE2CE300A221EC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 37 | CE19AB7B1ACE2CE300A221EC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 38 | CE19AB811ACE2CE300A221EC /* QQConfigurationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QQConfigurationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | CE19AB861ACE2CE300A221EC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | CE19AB871ACE2CE300A221EC /* QQConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QQConfigurationTests.swift; sourceTree = ""; }; 41 | CE19AB911ACE49B900A221EC /* MasterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterViewController.swift; sourceTree = ""; }; 42 | CE19AB931ACE49C400A221EC /* LeftsideViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftsideViewController.swift; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | CE19AB691ACE2CE300A221EC /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | CE19AB7E1ACE2CE300A221EC /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | CE19AB631ACE2CE300A221EC = { 64 | isa = PBXGroup; 65 | children = ( 66 | CE19AB6E1ACE2CE300A221EC /* QQConfiguration */, 67 | CE19AB841ACE2CE300A221EC /* QQConfigurationTests */, 68 | CE19AB6D1ACE2CE300A221EC /* Products */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | CE19AB6D1ACE2CE300A221EC /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | CE19AB6C1ACE2CE300A221EC /* QQConfiguration.app */, 76 | CE19AB811ACE2CE300A221EC /* QQConfigurationTests.xctest */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | CE19AB6E1ACE2CE300A221EC /* QQConfiguration */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | CE19AB711ACE2CE300A221EC /* AppDelegate.swift */, 85 | CE19AB731ACE2CE300A221EC /* ViewController.swift */, 86 | CE19AB911ACE49B900A221EC /* MasterViewController.swift */, 87 | CE19AB931ACE49C400A221EC /* LeftsideViewController.swift */, 88 | CE19AB751ACE2CE300A221EC /* Main.storyboard */, 89 | CE19AB781ACE2CE300A221EC /* Images.xcassets */, 90 | CE19AB7A1ACE2CE300A221EC /* LaunchScreen.xib */, 91 | CE19AB6F1ACE2CE300A221EC /* Supporting Files */, 92 | ); 93 | path = QQConfiguration; 94 | sourceTree = ""; 95 | }; 96 | CE19AB6F1ACE2CE300A221EC /* Supporting Files */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | CE19AB701ACE2CE300A221EC /* Info.plist */, 100 | ); 101 | name = "Supporting Files"; 102 | sourceTree = ""; 103 | }; 104 | CE19AB841ACE2CE300A221EC /* QQConfigurationTests */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | CE19AB871ACE2CE300A221EC /* QQConfigurationTests.swift */, 108 | CE19AB851ACE2CE300A221EC /* Supporting Files */, 109 | ); 110 | path = QQConfigurationTests; 111 | sourceTree = ""; 112 | }; 113 | CE19AB851ACE2CE300A221EC /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | CE19AB861ACE2CE300A221EC /* Info.plist */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | /* End PBXGroup section */ 122 | 123 | /* Begin PBXNativeTarget section */ 124 | CE19AB6B1ACE2CE300A221EC /* QQConfiguration */ = { 125 | isa = PBXNativeTarget; 126 | buildConfigurationList = CE19AB8B1ACE2CE300A221EC /* Build configuration list for PBXNativeTarget "QQConfiguration" */; 127 | buildPhases = ( 128 | CE19AB681ACE2CE300A221EC /* Sources */, 129 | CE19AB691ACE2CE300A221EC /* Frameworks */, 130 | CE19AB6A1ACE2CE300A221EC /* Resources */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = QQConfiguration; 137 | productName = QQConfiguration; 138 | productReference = CE19AB6C1ACE2CE300A221EC /* QQConfiguration.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | CE19AB801ACE2CE300A221EC /* QQConfigurationTests */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = CE19AB8E1ACE2CE300A221EC /* Build configuration list for PBXNativeTarget "QQConfigurationTests" */; 144 | buildPhases = ( 145 | CE19AB7D1ACE2CE300A221EC /* Sources */, 146 | CE19AB7E1ACE2CE300A221EC /* Frameworks */, 147 | CE19AB7F1ACE2CE300A221EC /* Resources */, 148 | ); 149 | buildRules = ( 150 | ); 151 | dependencies = ( 152 | CE19AB831ACE2CE300A221EC /* PBXTargetDependency */, 153 | ); 154 | name = QQConfigurationTests; 155 | productName = QQConfigurationTests; 156 | productReference = CE19AB811ACE2CE300A221EC /* QQConfigurationTests.xctest */; 157 | productType = "com.apple.product-type.bundle.unit-test"; 158 | }; 159 | /* End PBXNativeTarget section */ 160 | 161 | /* Begin PBXProject section */ 162 | CE19AB641ACE2CE300A221EC /* Project object */ = { 163 | isa = PBXProject; 164 | attributes = { 165 | LastUpgradeCheck = 0620; 166 | ORGANIZATIONNAME = blurryssky; 167 | TargetAttributes = { 168 | CE19AB6B1ACE2CE300A221EC = { 169 | CreatedOnToolsVersion = 6.2; 170 | }; 171 | CE19AB801ACE2CE300A221EC = { 172 | CreatedOnToolsVersion = 6.2; 173 | TestTargetID = CE19AB6B1ACE2CE300A221EC; 174 | }; 175 | }; 176 | }; 177 | buildConfigurationList = CE19AB671ACE2CE300A221EC /* Build configuration list for PBXProject "QQConfiguration" */; 178 | compatibilityVersion = "Xcode 3.2"; 179 | developmentRegion = English; 180 | hasScannedForEncodings = 0; 181 | knownRegions = ( 182 | en, 183 | Base, 184 | ); 185 | mainGroup = CE19AB631ACE2CE300A221EC; 186 | productRefGroup = CE19AB6D1ACE2CE300A221EC /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | CE19AB6B1ACE2CE300A221EC /* QQConfiguration */, 191 | CE19AB801ACE2CE300A221EC /* QQConfigurationTests */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | CE19AB6A1ACE2CE300A221EC /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | CE19AB771ACE2CE300A221EC /* Main.storyboard in Resources */, 202 | CE19AB7C1ACE2CE300A221EC /* LaunchScreen.xib in Resources */, 203 | CE19AB791ACE2CE300A221EC /* Images.xcassets in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | CE19AB7F1ACE2CE300A221EC /* Resources */ = { 208 | isa = PBXResourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXResourcesBuildPhase section */ 215 | 216 | /* Begin PBXSourcesBuildPhase section */ 217 | CE19AB681ACE2CE300A221EC /* Sources */ = { 218 | isa = PBXSourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | CE19AB741ACE2CE300A221EC /* ViewController.swift in Sources */, 222 | CE19AB721ACE2CE300A221EC /* AppDelegate.swift in Sources */, 223 | CE19AB941ACE49C400A221EC /* LeftsideViewController.swift in Sources */, 224 | CE19AB921ACE49B900A221EC /* MasterViewController.swift in Sources */, 225 | ); 226 | runOnlyForDeploymentPostprocessing = 0; 227 | }; 228 | CE19AB7D1ACE2CE300A221EC /* Sources */ = { 229 | isa = PBXSourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | CE19AB881ACE2CE300A221EC /* QQConfigurationTests.swift in Sources */, 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | }; 236 | /* End PBXSourcesBuildPhase section */ 237 | 238 | /* Begin PBXTargetDependency section */ 239 | CE19AB831ACE2CE300A221EC /* PBXTargetDependency */ = { 240 | isa = PBXTargetDependency; 241 | target = CE19AB6B1ACE2CE300A221EC /* QQConfiguration */; 242 | targetProxy = CE19AB821ACE2CE300A221EC /* PBXContainerItemProxy */; 243 | }; 244 | /* End PBXTargetDependency section */ 245 | 246 | /* Begin PBXVariantGroup section */ 247 | CE19AB751ACE2CE300A221EC /* Main.storyboard */ = { 248 | isa = PBXVariantGroup; 249 | children = ( 250 | CE19AB761ACE2CE300A221EC /* Base */, 251 | ); 252 | name = Main.storyboard; 253 | sourceTree = ""; 254 | }; 255 | CE19AB7A1ACE2CE300A221EC /* LaunchScreen.xib */ = { 256 | isa = PBXVariantGroup; 257 | children = ( 258 | CE19AB7B1ACE2CE300A221EC /* Base */, 259 | ); 260 | name = LaunchScreen.xib; 261 | sourceTree = ""; 262 | }; 263 | /* End PBXVariantGroup section */ 264 | 265 | /* Begin XCBuildConfiguration section */ 266 | CE19AB891ACE2CE300A221EC /* Debug */ = { 267 | isa = XCBuildConfiguration; 268 | buildSettings = { 269 | ALWAYS_SEARCH_USER_PATHS = NO; 270 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 271 | CLANG_CXX_LIBRARY = "libc++"; 272 | CLANG_ENABLE_MODULES = YES; 273 | CLANG_ENABLE_OBJC_ARC = YES; 274 | CLANG_WARN_BOOL_CONVERSION = YES; 275 | CLANG_WARN_CONSTANT_CONVERSION = YES; 276 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 277 | CLANG_WARN_EMPTY_BODY = YES; 278 | CLANG_WARN_ENUM_CONVERSION = YES; 279 | CLANG_WARN_INT_CONVERSION = YES; 280 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 281 | CLANG_WARN_UNREACHABLE_CODE = YES; 282 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 283 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 284 | COPY_PHASE_STRIP = NO; 285 | ENABLE_STRICT_OBJC_MSGSEND = YES; 286 | GCC_C_LANGUAGE_STANDARD = gnu99; 287 | GCC_DYNAMIC_NO_PIC = NO; 288 | GCC_OPTIMIZATION_LEVEL = 0; 289 | GCC_PREPROCESSOR_DEFINITIONS = ( 290 | "DEBUG=1", 291 | "$(inherited)", 292 | ); 293 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 298 | GCC_WARN_UNUSED_FUNCTION = YES; 299 | GCC_WARN_UNUSED_VARIABLE = YES; 300 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 301 | MTL_ENABLE_DEBUG_INFO = YES; 302 | ONLY_ACTIVE_ARCH = YES; 303 | SDKROOT = iphoneos; 304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 305 | }; 306 | name = Debug; 307 | }; 308 | CE19AB8A1ACE2CE300A221EC /* Release */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ALWAYS_SEARCH_USER_PATHS = NO; 312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 313 | CLANG_CXX_LIBRARY = "libc++"; 314 | CLANG_ENABLE_MODULES = YES; 315 | CLANG_ENABLE_OBJC_ARC = YES; 316 | CLANG_WARN_BOOL_CONVERSION = YES; 317 | CLANG_WARN_CONSTANT_CONVERSION = YES; 318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 319 | CLANG_WARN_EMPTY_BODY = YES; 320 | CLANG_WARN_ENUM_CONVERSION = YES; 321 | CLANG_WARN_INT_CONVERSION = YES; 322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 323 | CLANG_WARN_UNREACHABLE_CODE = YES; 324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 326 | COPY_PHASE_STRIP = NO; 327 | ENABLE_NS_ASSERTIONS = NO; 328 | ENABLE_STRICT_OBJC_MSGSEND = YES; 329 | GCC_C_LANGUAGE_STANDARD = gnu99; 330 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 331 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 332 | GCC_WARN_UNDECLARED_SELECTOR = YES; 333 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 334 | GCC_WARN_UNUSED_FUNCTION = YES; 335 | GCC_WARN_UNUSED_VARIABLE = YES; 336 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 337 | MTL_ENABLE_DEBUG_INFO = NO; 338 | SDKROOT = iphoneos; 339 | VALIDATE_PRODUCT = YES; 340 | }; 341 | name = Release; 342 | }; 343 | CE19AB8C1ACE2CE300A221EC /* Debug */ = { 344 | isa = XCBuildConfiguration; 345 | buildSettings = { 346 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 347 | INFOPLIST_FILE = QQConfiguration/Info.plist; 348 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 349 | PRODUCT_NAME = "$(TARGET_NAME)"; 350 | }; 351 | name = Debug; 352 | }; 353 | CE19AB8D1ACE2CE300A221EC /* Release */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | INFOPLIST_FILE = QQConfiguration/Info.plist; 358 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 359 | PRODUCT_NAME = "$(TARGET_NAME)"; 360 | }; 361 | name = Release; 362 | }; 363 | CE19AB8F1ACE2CE300A221EC /* Debug */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | BUNDLE_LOADER = "$(TEST_HOST)"; 367 | FRAMEWORK_SEARCH_PATHS = ( 368 | "$(SDKROOT)/Developer/Library/Frameworks", 369 | "$(inherited)", 370 | ); 371 | GCC_PREPROCESSOR_DEFINITIONS = ( 372 | "DEBUG=1", 373 | "$(inherited)", 374 | ); 375 | INFOPLIST_FILE = QQConfigurationTests/Info.plist; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/QQConfiguration.app/QQConfiguration"; 379 | }; 380 | name = Debug; 381 | }; 382 | CE19AB901ACE2CE300A221EC /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | BUNDLE_LOADER = "$(TEST_HOST)"; 386 | FRAMEWORK_SEARCH_PATHS = ( 387 | "$(SDKROOT)/Developer/Library/Frameworks", 388 | "$(inherited)", 389 | ); 390 | INFOPLIST_FILE = QQConfigurationTests/Info.plist; 391 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 392 | PRODUCT_NAME = "$(TARGET_NAME)"; 393 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/QQConfiguration.app/QQConfiguration"; 394 | }; 395 | name = Release; 396 | }; 397 | /* End XCBuildConfiguration section */ 398 | 399 | /* Begin XCConfigurationList section */ 400 | CE19AB671ACE2CE300A221EC /* Build configuration list for PBXProject "QQConfiguration" */ = { 401 | isa = XCConfigurationList; 402 | buildConfigurations = ( 403 | CE19AB891ACE2CE300A221EC /* Debug */, 404 | CE19AB8A1ACE2CE300A221EC /* Release */, 405 | ); 406 | defaultConfigurationIsVisible = 0; 407 | defaultConfigurationName = Release; 408 | }; 409 | CE19AB8B1ACE2CE300A221EC /* Build configuration list for PBXNativeTarget "QQConfiguration" */ = { 410 | isa = XCConfigurationList; 411 | buildConfigurations = ( 412 | CE19AB8C1ACE2CE300A221EC /* Debug */, 413 | CE19AB8D1ACE2CE300A221EC /* Release */, 414 | ); 415 | defaultConfigurationIsVisible = 0; 416 | }; 417 | CE19AB8E1ACE2CE300A221EC /* Build configuration list for PBXNativeTarget "QQConfigurationTests" */ = { 418 | isa = XCConfigurationList; 419 | buildConfigurations = ( 420 | CE19AB8F1ACE2CE300A221EC /* Debug */, 421 | CE19AB901ACE2CE300A221EC /* Release */, 422 | ); 423 | defaultConfigurationIsVisible = 0; 424 | }; 425 | /* End XCConfigurationList section */ 426 | }; 427 | rootObject = CE19AB641ACE2CE300A221EC /* Project object */; 428 | } 429 | -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/project.xcworkspace/xcshareddata/QQConfiguration.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | F98494A6-228B-4A5A-9571-DAAB0C9DA5D9 9 | IDESourceControlProjectName 10 | QQConfiguration 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 898FBC6C9793A51F7DD829D7A0940DA0C0D1F9B4 14 | https://github.com/shinept/QQConfiguration.git 15 | 16 | IDESourceControlProjectPath 17 | QQConfiguration.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 898FBC6C9793A51F7DD829D7A0940DA0C0D1F9B4 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/shinept/QQConfiguration.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 898FBC6C9793A51F7DD829D7A0940DA0C0D1F9B4 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 898FBC6C9793A51F7DD829D7A0940DA0C0D1F9B4 36 | IDESourceControlWCCName 37 | QQConfiguration 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/project.xcworkspace/xcuserdata/shinept.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinept/QQConfiguration/812b6b5ef0b05322701947f378c32c80673d6a32/QQConfiguration.xcodeproj/project.xcworkspace/xcuserdata/shinept.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/xcuserdata/shinept.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/xcuserdata/shinept.xcuserdatad/xcschemes/QQConfiguration.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /QQConfiguration.xcodeproj/xcuserdata/shinept.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | QQConfiguration.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | CE19AB6B1ACE2CE300A221EC 16 | 17 | primary 18 | 19 | 20 | CE19AB801ACE2CE300A221EC 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /QQConfiguration/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // QQConfiguration 4 | // 5 | // Created by 张亚东 on 15/4/3. 6 | // Copyright (c) 2015年 blurryssky. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /QQConfiguration/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /QQConfiguration/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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 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 | -------------------------------------------------------------------------------- /QQConfiguration/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /QQConfiguration/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | shinept.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 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 | 40 | 41 | -------------------------------------------------------------------------------- /QQConfiguration/LeftsideViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeftsideViewController.swift 3 | // QQConfiguration 4 | // 5 | // Created by 张亚东 on 15/4/3. 6 | // Copyright (c) 2015年 blurryssky. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LeftsideViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 30 | // Get the new view controller using segue.destinationViewController. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /QQConfiguration/MasterViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MasterViewController.swift 3 | // QQConfiguration 4 | // 5 | // Created by 张亚东 on 15/4/3. 6 | // Copyright (c) 2015年 blurryssky. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol MasterViewControllerDelegate { 12 | func MasterViewControllerShowButtonDidClicked() 13 | } 14 | 15 | class MasterViewController: UIViewController { 16 | var delegate : MasterViewControllerDelegate? 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | // Do any additional setup after loading the view. 21 | } 22 | 23 | @IBAction func respondsToShowButton(sender: UIBarButtonItem) { 24 | //2 25 | delegate?.MasterViewControllerShowButtonDidClicked() 26 | } 27 | 28 | /* 29 | // MARK: - Navigation 30 | 31 | // In a storyboard-based application, you will often want to do a little preparation before navigation 32 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 33 | // Get the new view controller using segue.destinationViewController. 34 | // Pass the selected object to the new view controller. 35 | } 36 | */ 37 | 38 | } 39 | -------------------------------------------------------------------------------- /QQConfiguration/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // QQConfiguration 4 | // 5 | // Created by 张亚东 on 15/4/3. 6 | // Copyright (c) 2015年 blurryssky. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let ZDScreenWidth = UIScreen.mainScreen().bounds.width 12 | let ZDScreenHeight = UIScreen.mainScreen().bounds.height 13 | //base on iPhone 6,屏幕系数 14 | let ZDScreenFactorWidth = ZDScreenWidth / 375.0 15 | let ZDScreenFactorHeight = ZDScreenHeight / 667.0 16 | 17 | class ViewController: UIViewController , MasterViewControllerDelegate{ 18 | 19 | @IBOutlet weak var masterContainerView: UIView! 20 | @IBOutlet weak var leftsideContainerView: UIView! 21 | 22 | var leftContainerViewShowed = false 23 | 24 | @IBOutlet weak var leftContainerViewLayoutConstraintTralingToEdge: NSLayoutConstraint! 25 | 26 | let leftsideContainerViewOffsetX = -220 * ZDScreenFactorWidth 27 | let masterContainerViewOffsetX = 305 * ZDScreenFactorWidth 28 | 29 | //左视图出现需要超过的拖动的距离 30 | let paddingSpaceToLeftEdge = 80 * ZDScreenFactorWidth 31 | 32 | //显示出来的左视图的右边缘距离屏幕的宽度 33 | let marginToRightEdge = 80 * ZDScreenFactorWidth 34 | 35 | lazy var leftMaskView : UIView! = { 36 | let view = UIView() 37 | view.backgroundColor = UIColor.blackColor() 38 | view.alpha = 1 39 | return view 40 | }() 41 | 42 | lazy var masterMaskView : UIView! = { 43 | let view = UIView() 44 | view.backgroundColor = UIColor.blackColor() 45 | view.alpha = 0 46 | return view 47 | }() 48 | 49 | //Gesture 50 | lazy var tap:UITapGestureRecognizer = { 51 | let tap = UITapGestureRecognizer(target: self, action: "respondsToTap:") 52 | return tap 53 | }() 54 | 55 | lazy var leftScreenEdgePan :UIScreenEdgePanGestureRecognizer = { 56 | let pan = UIScreenEdgePanGestureRecognizer(target: self, action: "respondsToPan:") 57 | pan.edges = UIRectEdge.Left 58 | return pan 59 | }() 60 | 61 | lazy var pan:UIPanGestureRecognizer = { 62 | let pan = UIPanGestureRecognizer(target: self, action: "respondsToPan:") 63 | return pan 64 | }() 65 | 66 | override func viewDidLoad() { 67 | super.viewDidLoad() 68 | // Do any additional setup after loading the view, typically from a nib. 69 | initialyConfiguration() 70 | } 71 | 72 | func initialyConfiguration() { 73 | 74 | leftContainerViewLayoutConstraintTralingToEdge.constant = 80 * ZDScreenFactorWidth 75 | //5 76 | view.layoutIfNeeded() 77 | 78 | //leftsideContainerView 79 | leftMaskView.frame = CGRectMake(0, 0, 80 | leftsideContainerView.bounds.width , 81 | leftsideContainerView.bounds.height) 82 | 83 | leftsideContainerView.addSubview(leftMaskView) 84 | 85 | //masterView 86 | masterMaskView.frame = CGRectMake(0, 0, ZDScreenWidth, ZDScreenHeight) 87 | masterContainerView.addSubview(masterMaskView) 88 | 89 | //add tap gesture 90 | masterMaskView.addGestureRecognizer(tap) 91 | 92 | //注意是加在view上 93 | view.addGestureRecognizer(leftScreenEdgePan) 94 | //1 95 | leftsideContainerView.transform = CGAffineTransformMakeScale(0.5, 0.5) 96 | leftsideContainerView.transform = CGAffineTransformTranslate(leftsideContainerView.transform, leftsideContainerViewOffsetX, 0) 97 | 98 | 99 | } 100 | 101 | //3 102 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 103 | let vc = segue.destinationViewController as! UIViewController 104 | 105 | if vc.isKindOfClass(UINavigationController) { 106 | let naviVC = vc as! UINavigationController 107 | let topVC = naviVC.topViewController 108 | 109 | if topVC.isKindOfClass(MasterViewController) { 110 | let masterVC = topVC as! MasterViewController 111 | masterVC.delegate = self 112 | } 113 | } 114 | } 115 | 116 | //#MARK:MasterViewControllerDelegate 117 | //4 118 | func MasterViewControllerShowButtonDidClicked() { 119 | showLeftContainerViewAnimated(true, completion: { () -> Void in 120 | 121 | }) 122 | } 123 | 124 | //#MARK:Gesture 125 | func respondsToTap(sender :UITapGestureRecognizer){ 126 | dismissLeftContainerViewAnimated(true, completion: { () -> Void in 127 | 128 | }) 129 | } 130 | 131 | func respondsToPan(sender: UIPanGestureRecognizer) { 132 | 133 | let translationPoint = sender.translationInView(masterContainerView) 134 | 135 | var translationX : CGFloat? 136 | 137 | //建立静态变量 138 | struct Static { 139 | static var panStartPoint : CGPoint! 140 | } 141 | 142 | switch sender.state { 143 | case UIGestureRecognizerState.Began: 144 | Static.panStartPoint = translationPoint 145 | 146 | case .Changed: 147 | translationX = translationPoint.x - Static.panStartPoint!.x 148 | 149 | //从左往右拖的时候拖出了左视图显示时的宽度 150 | if abs(translationX!) > ZDScreenWidth - marginToRightEdge { 151 | return 152 | } 153 | //caculator the factor 154 | var factor = translationX! / (ZDScreenWidth - marginToRightEdge) 155 | 156 | //从左往右滑的情况,系数需要作调整 157 | if leftContainerViewShowed { 158 | factor = 1 + factor 159 | } 160 | 161 | //从右往左拖了一点后立刻往右拖的情况 162 | if leftContainerViewShowed { 163 | if translationX! > 0 { 164 | showLeftContainerViewAnimated(false, completion: { () -> Void in 165 | 166 | }) 167 | 168 | return 169 | } 170 | } 171 | //从左往右拖了一点后立刻往左拖的情况 172 | else { 173 | if translationX! < 0 { 174 | 175 | dismissLeftContainerViewAnimated(false, completion: { () -> Void in 176 | 177 | }) 178 | return 179 | } 180 | } 181 | 182 | //由于scale一开始就是0.5倍,所以相应的乘以0.5 183 | self.leftsideContainerView.transform = CGAffineTransformMakeTranslation(self.leftsideContainerViewOffsetX * (1 - factor) * 0.5, 0) 184 | //由0.5 -> 1 185 | self.leftsideContainerView.transform = CGAffineTransformScale(self.leftsideContainerView.transform, 0.5 + 0.5 * factor, 0.5 + 0.5 * factor) 186 | //1 -> 0 187 | self.leftMaskView.alpha = 1 - factor 188 | //1 -> 0.9 189 | self.masterContainerView.transform = CGAffineTransformMakeScale(1 - 0.1 * factor, 1 - 0.1 * factor) 190 | //做一些偏移 191 | self.masterContainerView.transform = CGAffineTransformTranslate(self.masterContainerView.transform, self.masterContainerViewOffsetX * factor , 0) 192 | //0 -> 0.5 193 | self.masterMaskView.alpha = 0.5 * factor 194 | 195 | 196 | case .Ended: 197 | 198 | translationX = abs(translationPoint.x - Static.panStartPoint!.x) 199 | 200 | let velocity = pan.velocityInView(view) 201 | 202 | //如果滑动结束时,水平速度的方向向右 203 | if velocity.x > 0 { 204 | showLeftContainerViewAnimated(true, completion: { () -> Void in 205 | 206 | }) 207 | } 208 | else if velocity.x < 0{ 209 | dismissLeftContainerViewAnimated(true, completion: { () -> Void in 210 | 211 | }) 212 | } 213 | //不知为什么,触发ScreenEdgePan的时候velocity为0,所以我做了以下判断,有发现原因的开发者可以告知我一下 214 | else { 215 | if translationX > paddingSpaceToLeftEdge { 216 | showLeftContainerViewAnimated(true, completion: { () -> Void in 217 | 218 | }) 219 | } 220 | else { 221 | dismissLeftContainerViewAnimated(true, completion: { () -> Void in 222 | 223 | }) 224 | } 225 | } 226 | Static.panStartPoint = nil 227 | default:break 228 | } 229 | } 230 | 231 | func showLeftContainerViewAnimated(animated:Bool, completion:() -> Void) { 232 | 233 | var duration = animated ? 0.3 : 0 234 | 235 | UIView.animateWithDuration(duration, animations: { () -> Void in 236 | self.leftsideContainerView.transform = CGAffineTransformIdentity 237 | 238 | self.masterContainerView.transform = CGAffineTransformMakeScale(0.9, 0.9) 239 | self.masterContainerView.transform = CGAffineTransformTranslate(self.masterContainerView.transform, self.masterContainerViewOffsetX, 0) 240 | 241 | self.leftMaskView.alpha = 0 242 | self.masterMaskView.alpha = 0.5 243 | }) { (_) -> Void in 244 | self.leftContainerViewShowed = true 245 | self.view.removeGestureRecognizer(self.leftScreenEdgePan) 246 | self.masterMaskView.addGestureRecognizer(self.pan) 247 | } 248 | } 249 | func dismissLeftContainerViewAnimated(animated:Bool ,completion:() -> Void) { 250 | UIView.animateWithDuration(0.3, animations: { () -> Void in 251 | 252 | var duration = animated ? 0.3 : 0 253 | 254 | self.leftsideContainerView.transform = CGAffineTransformMakeScale(0.5, 0.5) 255 | self.leftsideContainerView.transform = CGAffineTransformTranslate(self.leftsideContainerView.transform, self.leftsideContainerViewOffsetX, 0) 256 | 257 | self.masterContainerView.transform = CGAffineTransformIdentity 258 | 259 | self.leftMaskView.alpha = 1 260 | self.masterMaskView.alpha = 0 261 | }) { (_) -> Void in 262 | self.leftContainerViewShowed = false 263 | self.view.addGestureRecognizer(self.leftScreenEdgePan) 264 | self.masterMaskView.removeGestureRecognizer(self.pan) 265 | } 266 | } 267 | } 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /QQConfigurationGIF.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinept/QQConfiguration/812b6b5ef0b05322701947f378c32c80673d6a32/QQConfigurationGIF.gif -------------------------------------------------------------------------------- /QQConfigurationTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | shinept.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /QQConfigurationTests/QQConfigurationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QQConfigurationTests.swift 3 | // QQConfigurationTests 4 | // 5 | // Created by 张亚东 on 15/4/3. 6 | // Copyright (c) 2015年 blurryssky. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class QQConfigurationTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QQConfiguration 2 | --------------------------------------------------------------------------------