├── LICENSE ├── README.md ├── Screen Sizes Simulator-Info.plist ├── Screen Sizes Simulator.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── felipe.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── Screen Sizes Simulator ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── bird1.imageset │ │ ├── Contents.json │ │ └── bird1.jpg │ ├── bird2.imageset │ │ ├── Contents.json │ │ └── bird2.jpg │ ├── frog1.imageset │ │ ├── Contents.json │ │ └── frog1.jpg │ ├── frog2.imageset │ │ ├── Contents.json │ │ └── frog2.jpg │ ├── mammal1.imageset │ │ ├── Contents.json │ │ └── mammal1.jpg │ └── mammal2.imageset │ │ ├── Contents.json │ │ └── mammal2.jpg ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Extensions.swift ├── Info.plist ├── SizesSimulator.storyboard ├── SizesSimulatorViewController.swift └── ViewController.swift ├── SizesSimulator ├── SizesSimulator.storyboard └── SizesSimulatorViewController.swift └── readme_pt.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 felipeferri 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [Esta página em português](/readme_pt.md) 2 | 3 | # ScreenSizesSimulator 4 | Use a single iOS device for testing your app in all iPhone sizes 5 | 6 | Do you test for different screen sizes when developing your iOS apps? You know you should, right? 7 | 8 | Running the same app on different simulators can take too long, and having several devices is inviable for many of us. That's why the Screen Sizes Simulator can be a good idea for you. 9 | 10 | Screen Sizes Simulator is a storyboard template and a neat control panel that allow you to run your app on screens mimicking all current iPhone models sizes. See below what I mean. All screenshots were obtained by running the Demo app included in this repo on the iPhone6 simulator. 11 | 12 | iPhone6 regular size | iPhone5 size on iPhone6 13 | :-------------------------:|:-------------------------: 14 | ![](/../screenshots/screenshots/iPhone6.png) | ![](/../screenshots/screenshots/iPhone5_panel.png) 15 | 16 | iPhone4 size on iPhone6 | iPhone4 size landscape 17 | :-------------------------:|:-------------------------: 18 | ![](/../screenshots/screenshots/iPhone4_panel.png) | ![](/../screenshots/screenshots/iPhone4_landscape.png) 19 | 20 | If you run the Screen Sizes Simulator on an iPad you can run your app in all iPhone sizes and they will show in the real device size. Maybe you have an iPhone 4S (my case ugh) and you want to see how the layout for the iPhone6 runs on a phone. Then you can use the "fit" option in the panel to zoom out the app until if fits on your phone screen, maintaining all the UI elements proportions. 21 | 22 | *** 23 | ## Installing Screen Sizes Simulator on your app 24 | Please check the demo project if you are in doubt. 25 | 26 | 1. Copy the "Screen Sizes" folder into your project. 27 | 2. Locate your Initial View Controller on your project storyboard and set its Storyboard ID as "SwipeViewController" on the Identity Inspector. 28 | 3. Open the SizesSimulator storyboard and make sure the Storyboard reference block is pointing to your Main storyboard (unless you changed your main storyboard name the default value should suffice). 29 | 4. Open your project target on the General tab and set Main Interface as "SizesSimulator". 30 | 5. Run your project on a device or the simulator and everything should work. 31 | 32 | You must remember to change your Main Interface back to your main storyboard when releasing your app to the AppStore. If you feel bold, you can create a new target specifically for the Screen Sizes Simulator instead of changing your main target Main Interface. Check the demo app for an example. 33 | 34 | ## Dealing with modal view controllers 35 | By default new modal controllers will be pushed over the full app screen, but what we really need is that they're presented just over the simulator view. In order to allow this please make sure that all modal segues have "Over Current Context" set as Presentation type. 36 | 37 | ## Using the Screen Sizes Simulator 38 | The Screen Sizes Simulator has a small control panel on top. If you tap on it it will disappear; if you shake your phone it will appear again. 39 | 40 | You can select four different iPhone sizes: iPhone4S, iPhone5/SE, iPhone6S/7S, iPhone6S+/7S+. 41 | 42 | You can also select four zoom levels: 1x, 2x, fit and fill. 43 | 44 | * 1x shows the normal screen size. You should use this when running the app on a device larger than the screen you want to show (for example, running the iPhone5S screen on an iPhone6S). 45 | * 2x shows double the screen size. This actually is only useful if you're running your app on an iPad. It is similar to the zoom option available when you run an iPhone (non-universal) app on iPad. 46 | * fit will apply a zoom level that fits the app on the current phone screen. This is the ideal to use when displaying larger screens than your iPhone. For example, for showing the iPhone6S size on an iPhone4S device. 47 | * fill will apply a zoom level that fills the phone screen with the selected display size. 48 | 49 | ## To do (pull requests are welcome) 50 | * Create a podfile 51 | * Make a coded version of the Simulator wich doesn't require messing around with targets and info.plists 52 | * If you use size classes the simulator will not respond correctly when running on an iPad becase the size classes for height and width of the iPad even when on landscape are not the same that for an iPhone. I don't know how to solve this. 53 | -------------------------------------------------------------------------------- /Screen Sizes Simulator-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | SizesSimulator 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Screen Sizes Simulator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 55CD6E711EC35B3500214D7F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E701EC35B3500214D7F /* AppDelegate.swift */; }; 11 | 55CD6E731EC35B3500214D7F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E721EC35B3500214D7F /* ViewController.swift */; }; 12 | 55CD6E761EC35B3500214D7F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E741EC35B3500214D7F /* Main.storyboard */; }; 13 | 55CD6E781EC35B3500214D7F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E771EC35B3500214D7F /* Assets.xcassets */; }; 14 | 55CD6E7B1EC35B3500214D7F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E791EC35B3500214D7F /* LaunchScreen.storyboard */; }; 15 | 55CD6E831EC35F6500214D7F /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E821EC35F6500214D7F /* Extensions.swift */; }; 16 | 55CD6E871EC35FEE00214D7F /* SizesSimulator.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E851EC35FEE00214D7F /* SizesSimulator.storyboard */; }; 17 | 55CD6E881EC35FEE00214D7F /* SizesSimulatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E861EC35FEE00214D7F /* SizesSimulatorViewController.swift */; }; 18 | 55CD6E8B1EC3616700214D7F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E721EC35B3500214D7F /* ViewController.swift */; }; 19 | 55CD6E8C1EC3616700214D7F /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E821EC35F6500214D7F /* Extensions.swift */; }; 20 | 55CD6E8D1EC3616700214D7F /* SizesSimulatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E861EC35FEE00214D7F /* SizesSimulatorViewController.swift */; }; 21 | 55CD6E8E1EC3616700214D7F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55CD6E701EC35B3500214D7F /* AppDelegate.swift */; }; 22 | 55CD6E911EC3616700214D7F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E791EC35B3500214D7F /* LaunchScreen.storyboard */; }; 23 | 55CD6E921EC3616700214D7F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E771EC35B3500214D7F /* Assets.xcassets */; }; 24 | 55CD6E931EC3616700214D7F /* SizesSimulator.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E851EC35FEE00214D7F /* SizesSimulator.storyboard */; }; 25 | 55CD6E941EC3616700214D7F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55CD6E741EC35B3500214D7F /* Main.storyboard */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 55CD6E6D1EC35B3500214D7F /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 55CD6E701EC35B3500214D7F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 31 | 55CD6E721EC35B3500214D7F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 32 | 55CD6E751EC35B3500214D7F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | 55CD6E771EC35B3500214D7F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 34 | 55CD6E7A1EC35B3500214D7F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 35 | 55CD6E7C1EC35B3500214D7F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 55CD6E821EC35F6500214D7F /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 37 | 55CD6E851EC35FEE00214D7F /* SizesSimulator.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SizesSimulator.storyboard; sourceTree = ""; }; 38 | 55CD6E861EC35FEE00214D7F /* SizesSimulatorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SizesSimulatorViewController.swift; sourceTree = ""; }; 39 | 55CD6E981EC3616700214D7F /* Screen Sizes Simulator copy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Screen Sizes Simulator copy.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 55CD6E991EC3616700214D7F /* Screen Sizes Simulator-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Screen Sizes Simulator-Info.plist"; path = "/Users/felipe/Documents/Projetos/Screen Sizes Simulator/Screen Sizes Simulator/Screen Sizes Simulator-Info.plist"; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 55CD6E6A1EC35B3500214D7F /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | 55CD6E8F1EC3616700214D7F /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 55CD6E641EC35B3500214D7F = { 62 | isa = PBXGroup; 63 | children = ( 64 | 55CD6E6F1EC35B3500214D7F /* Screen Sizes Simulator */, 65 | 55CD6E6E1EC35B3500214D7F /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | 55CD6E6E1EC35B3500214D7F /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 55CD6E6D1EC35B3500214D7F /* Demo.app */, 73 | 55CD6E981EC3616700214D7F /* Screen Sizes Simulator copy.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 55CD6E6F1EC35B3500214D7F /* Screen Sizes Simulator */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 55CD6E841EC35FD600214D7F /* Screen Sizes */, 82 | 55CD6E701EC35B3500214D7F /* AppDelegate.swift */, 83 | 55CD6E821EC35F6500214D7F /* Extensions.swift */, 84 | 55CD6E721EC35B3500214D7F /* ViewController.swift */, 85 | 55CD6E741EC35B3500214D7F /* Main.storyboard */, 86 | 55CD6E771EC35B3500214D7F /* Assets.xcassets */, 87 | 55CD6E791EC35B3500214D7F /* LaunchScreen.storyboard */, 88 | 55CD6E7C1EC35B3500214D7F /* Info.plist */, 89 | 55CD6E991EC3616700214D7F /* Screen Sizes Simulator-Info.plist */, 90 | ); 91 | path = "Screen Sizes Simulator"; 92 | sourceTree = ""; 93 | }; 94 | 55CD6E841EC35FD600214D7F /* Screen Sizes */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 55CD6E851EC35FEE00214D7F /* SizesSimulator.storyboard */, 98 | 55CD6E861EC35FEE00214D7F /* SizesSimulatorViewController.swift */, 99 | ); 100 | name = "Screen Sizes"; 101 | sourceTree = ""; 102 | }; 103 | /* End PBXGroup section */ 104 | 105 | /* Begin PBXNativeTarget section */ 106 | 55CD6E6C1EC35B3500214D7F /* Demo */ = { 107 | isa = PBXNativeTarget; 108 | buildConfigurationList = 55CD6E7F1EC35B3500214D7F /* Build configuration list for PBXNativeTarget "Demo" */; 109 | buildPhases = ( 110 | 55CD6E691EC35B3500214D7F /* Sources */, 111 | 55CD6E6A1EC35B3500214D7F /* Frameworks */, 112 | 55CD6E6B1EC35B3500214D7F /* Resources */, 113 | ); 114 | buildRules = ( 115 | ); 116 | dependencies = ( 117 | ); 118 | name = Demo; 119 | productName = "Screen Sizes Simulator"; 120 | productReference = 55CD6E6D1EC35B3500214D7F /* Demo.app */; 121 | productType = "com.apple.product-type.application"; 122 | }; 123 | 55CD6E891EC3616700214D7F /* Screen Sizes Simulator copy */ = { 124 | isa = PBXNativeTarget; 125 | buildConfigurationList = 55CD6E951EC3616700214D7F /* Build configuration list for PBXNativeTarget "Screen Sizes Simulator copy" */; 126 | buildPhases = ( 127 | 55CD6E8A1EC3616700214D7F /* Sources */, 128 | 55CD6E8F1EC3616700214D7F /* Frameworks */, 129 | 55CD6E901EC3616700214D7F /* Resources */, 130 | ); 131 | buildRules = ( 132 | ); 133 | dependencies = ( 134 | ); 135 | name = "Screen Sizes Simulator copy"; 136 | productName = "Screen Sizes Simulator"; 137 | productReference = 55CD6E981EC3616700214D7F /* Screen Sizes Simulator copy.app */; 138 | productType = "com.apple.product-type.application"; 139 | }; 140 | /* End PBXNativeTarget section */ 141 | 142 | /* Begin PBXProject section */ 143 | 55CD6E651EC35B3500214D7F /* Project object */ = { 144 | isa = PBXProject; 145 | attributes = { 146 | LastSwiftUpdateCheck = 0830; 147 | LastUpgradeCheck = 0830; 148 | ORGANIZATIONNAME = "Felipe Augusto Sviaghin Ferri"; 149 | TargetAttributes = { 150 | 55CD6E6C1EC35B3500214D7F = { 151 | CreatedOnToolsVersion = 8.3.2; 152 | DevelopmentTeam = ZT28PLWG78; 153 | ProvisioningStyle = Automatic; 154 | }; 155 | 55CD6E891EC3616700214D7F = { 156 | DevelopmentTeam = ZT28PLWG78; 157 | }; 158 | }; 159 | }; 160 | buildConfigurationList = 55CD6E681EC35B3500214D7F /* Build configuration list for PBXProject "Screen Sizes Simulator" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = English; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | en, 166 | Base, 167 | ); 168 | mainGroup = 55CD6E641EC35B3500214D7F; 169 | productRefGroup = 55CD6E6E1EC35B3500214D7F /* Products */; 170 | projectDirPath = ""; 171 | projectRoot = ""; 172 | targets = ( 173 | 55CD6E6C1EC35B3500214D7F /* Demo */, 174 | 55CD6E891EC3616700214D7F /* Screen Sizes Simulator copy */, 175 | ); 176 | }; 177 | /* End PBXProject section */ 178 | 179 | /* Begin PBXResourcesBuildPhase section */ 180 | 55CD6E6B1EC35B3500214D7F /* Resources */ = { 181 | isa = PBXResourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | 55CD6E7B1EC35B3500214D7F /* LaunchScreen.storyboard in Resources */, 185 | 55CD6E781EC35B3500214D7F /* Assets.xcassets in Resources */, 186 | 55CD6E871EC35FEE00214D7F /* SizesSimulator.storyboard in Resources */, 187 | 55CD6E761EC35B3500214D7F /* Main.storyboard in Resources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | 55CD6E901EC3616700214D7F /* Resources */ = { 192 | isa = PBXResourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | 55CD6E911EC3616700214D7F /* LaunchScreen.storyboard in Resources */, 196 | 55CD6E921EC3616700214D7F /* Assets.xcassets in Resources */, 197 | 55CD6E931EC3616700214D7F /* SizesSimulator.storyboard in Resources */, 198 | 55CD6E941EC3616700214D7F /* Main.storyboard in Resources */, 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | /* End PBXResourcesBuildPhase section */ 203 | 204 | /* Begin PBXSourcesBuildPhase section */ 205 | 55CD6E691EC35B3500214D7F /* Sources */ = { 206 | isa = PBXSourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 55CD6E731EC35B3500214D7F /* ViewController.swift in Sources */, 210 | 55CD6E831EC35F6500214D7F /* Extensions.swift in Sources */, 211 | 55CD6E881EC35FEE00214D7F /* SizesSimulatorViewController.swift in Sources */, 212 | 55CD6E711EC35B3500214D7F /* AppDelegate.swift in Sources */, 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | 55CD6E8A1EC3616700214D7F /* Sources */ = { 217 | isa = PBXSourcesBuildPhase; 218 | buildActionMask = 2147483647; 219 | files = ( 220 | 55CD6E8B1EC3616700214D7F /* ViewController.swift in Sources */, 221 | 55CD6E8C1EC3616700214D7F /* Extensions.swift in Sources */, 222 | 55CD6E8D1EC3616700214D7F /* SizesSimulatorViewController.swift in Sources */, 223 | 55CD6E8E1EC3616700214D7F /* AppDelegate.swift in Sources */, 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | /* End PBXSourcesBuildPhase section */ 228 | 229 | /* Begin PBXVariantGroup section */ 230 | 55CD6E741EC35B3500214D7F /* Main.storyboard */ = { 231 | isa = PBXVariantGroup; 232 | children = ( 233 | 55CD6E751EC35B3500214D7F /* Base */, 234 | ); 235 | name = Main.storyboard; 236 | sourceTree = ""; 237 | }; 238 | 55CD6E791EC35B3500214D7F /* LaunchScreen.storyboard */ = { 239 | isa = PBXVariantGroup; 240 | children = ( 241 | 55CD6E7A1EC35B3500214D7F /* Base */, 242 | ); 243 | name = LaunchScreen.storyboard; 244 | sourceTree = ""; 245 | }; 246 | /* End PBXVariantGroup section */ 247 | 248 | /* Begin XCBuildConfiguration section */ 249 | 55CD6E7D1EC35B3500214D7F /* Debug */ = { 250 | isa = XCBuildConfiguration; 251 | buildSettings = { 252 | ALWAYS_SEARCH_USER_PATHS = NO; 253 | CLANG_ANALYZER_NONNULL = YES; 254 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 255 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 256 | CLANG_CXX_LIBRARY = "libc++"; 257 | CLANG_ENABLE_MODULES = YES; 258 | CLANG_ENABLE_OBJC_ARC = YES; 259 | CLANG_WARN_BOOL_CONVERSION = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 262 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 263 | CLANG_WARN_EMPTY_BODY = YES; 264 | CLANG_WARN_ENUM_CONVERSION = YES; 265 | CLANG_WARN_INFINITE_RECURSION = YES; 266 | CLANG_WARN_INT_CONVERSION = YES; 267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 268 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 269 | CLANG_WARN_UNREACHABLE_CODE = YES; 270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 271 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 272 | COPY_PHASE_STRIP = NO; 273 | DEBUG_INFORMATION_FORMAT = dwarf; 274 | ENABLE_STRICT_OBJC_MSGSEND = YES; 275 | ENABLE_TESTABILITY = YES; 276 | GCC_C_LANGUAGE_STANDARD = gnu99; 277 | GCC_DYNAMIC_NO_PIC = NO; 278 | GCC_NO_COMMON_BLOCKS = YES; 279 | GCC_OPTIMIZATION_LEVEL = 0; 280 | GCC_PREPROCESSOR_DEFINITIONS = ( 281 | "DEBUG=1", 282 | "$(inherited)", 283 | ); 284 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 285 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 286 | GCC_WARN_UNDECLARED_SELECTOR = YES; 287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 288 | GCC_WARN_UNUSED_FUNCTION = YES; 289 | GCC_WARN_UNUSED_VARIABLE = YES; 290 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 291 | MTL_ENABLE_DEBUG_INFO = YES; 292 | ONLY_ACTIVE_ARCH = YES; 293 | SDKROOT = iphoneos; 294 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 295 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 296 | TARGETED_DEVICE_FAMILY = "1,2"; 297 | }; 298 | name = Debug; 299 | }; 300 | 55CD6E7E1EC35B3500214D7F /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | CLANG_ANALYZER_NONNULL = YES; 305 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 306 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 307 | CLANG_CXX_LIBRARY = "libc++"; 308 | CLANG_ENABLE_MODULES = YES; 309 | CLANG_ENABLE_OBJC_ARC = YES; 310 | CLANG_WARN_BOOL_CONVERSION = YES; 311 | CLANG_WARN_CONSTANT_CONVERSION = YES; 312 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 313 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 314 | CLANG_WARN_EMPTY_BODY = YES; 315 | CLANG_WARN_ENUM_CONVERSION = YES; 316 | CLANG_WARN_INFINITE_RECURSION = YES; 317 | CLANG_WARN_INT_CONVERSION = YES; 318 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 319 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 320 | CLANG_WARN_UNREACHABLE_CODE = YES; 321 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 322 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 323 | COPY_PHASE_STRIP = NO; 324 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 325 | ENABLE_NS_ASSERTIONS = NO; 326 | ENABLE_STRICT_OBJC_MSGSEND = YES; 327 | GCC_C_LANGUAGE_STANDARD = gnu99; 328 | GCC_NO_COMMON_BLOCKS = YES; 329 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 330 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 331 | GCC_WARN_UNDECLARED_SELECTOR = YES; 332 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 333 | GCC_WARN_UNUSED_FUNCTION = YES; 334 | GCC_WARN_UNUSED_VARIABLE = YES; 335 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 336 | MTL_ENABLE_DEBUG_INFO = NO; 337 | SDKROOT = iphoneos; 338 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 339 | TARGETED_DEVICE_FAMILY = "1,2"; 340 | VALIDATE_PRODUCT = YES; 341 | }; 342 | name = Release; 343 | }; 344 | 55CD6E801EC35B3500214D7F /* Debug */ = { 345 | isa = XCBuildConfiguration; 346 | buildSettings = { 347 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 348 | DEVELOPMENT_TEAM = ZT28PLWG78; 349 | INFOPLIST_FILE = "Screen Sizes Simulator/Info.plist"; 350 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 351 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 352 | PRODUCT_BUNDLE_IDENTIFIER = "com.sailscooter.Screen-Sizes-Simulator"; 353 | PRODUCT_NAME = "$(TARGET_NAME)"; 354 | SWIFT_VERSION = 3.0; 355 | }; 356 | name = Debug; 357 | }; 358 | 55CD6E811EC35B3500214D7F /* Release */ = { 359 | isa = XCBuildConfiguration; 360 | buildSettings = { 361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 362 | DEVELOPMENT_TEAM = ZT28PLWG78; 363 | INFOPLIST_FILE = "Screen Sizes Simulator/Info.plist"; 364 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 365 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 366 | PRODUCT_BUNDLE_IDENTIFIER = "com.sailscooter.Screen-Sizes-Simulator"; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | SWIFT_VERSION = 3.0; 369 | }; 370 | name = Release; 371 | }; 372 | 55CD6E961EC3616700214D7F /* Debug */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 376 | DEVELOPMENT_TEAM = ZT28PLWG78; 377 | INFOPLIST_FILE = "$(SRCROOT)/Screen Sizes Simulator-Info.plist"; 378 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 379 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 380 | PRODUCT_BUNDLE_IDENTIFIER = "com.sailscooter.Screen-Sizes-Simulator"; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | SWIFT_VERSION = 3.0; 383 | }; 384 | name = Debug; 385 | }; 386 | 55CD6E971EC3616700214D7F /* Release */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 390 | DEVELOPMENT_TEAM = ZT28PLWG78; 391 | INFOPLIST_FILE = "$(SRCROOT)/Screen Sizes Simulator-Info.plist"; 392 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 394 | PRODUCT_BUNDLE_IDENTIFIER = "com.sailscooter.Screen-Sizes-Simulator"; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SWIFT_VERSION = 3.0; 397 | }; 398 | name = Release; 399 | }; 400 | /* End XCBuildConfiguration section */ 401 | 402 | /* Begin XCConfigurationList section */ 403 | 55CD6E681EC35B3500214D7F /* Build configuration list for PBXProject "Screen Sizes Simulator" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | 55CD6E7D1EC35B3500214D7F /* Debug */, 407 | 55CD6E7E1EC35B3500214D7F /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | 55CD6E7F1EC35B3500214D7F /* Build configuration list for PBXNativeTarget "Demo" */ = { 413 | isa = XCConfigurationList; 414 | buildConfigurations = ( 415 | 55CD6E801EC35B3500214D7F /* Debug */, 416 | 55CD6E811EC35B3500214D7F /* Release */, 417 | ); 418 | defaultConfigurationIsVisible = 0; 419 | }; 420 | 55CD6E951EC3616700214D7F /* Build configuration list for PBXNativeTarget "Screen Sizes Simulator copy" */ = { 421 | isa = XCConfigurationList; 422 | buildConfigurations = ( 423 | 55CD6E961EC3616700214D7F /* Debug */, 424 | 55CD6E971EC3616700214D7F /* Release */, 425 | ); 426 | defaultConfigurationIsVisible = 0; 427 | defaultConfigurationName = Release; 428 | }; 429 | /* End XCConfigurationList section */ 430 | }; 431 | rootObject = 55CD6E651EC35B3500214D7F /* Project object */; 432 | } 433 | -------------------------------------------------------------------------------- /Screen Sizes Simulator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Screen Sizes Simulator.xcodeproj/xcuserdata/felipe.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Screen Sizes Simulator.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 55CD6E6C1EC35B3500214D7F 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Screen Sizes Simulator 4 | // 5 | // Created by Felipe Augusto Sviaghin Ferri on 10/5/17. 6 | // Copyright © 2017 Felipe Augusto Sviaghin Ferri. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 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 invalidate graphics rendering callbacks. 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 active 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 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/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 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/bird1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bird1.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/bird1.imageset/bird1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipeferri/ScreenSizesSimulator/c0e29586d355583bc396e2dcf8ed9cab0e0bab64/Screen Sizes Simulator/Assets.xcassets/bird1.imageset/bird1.jpg -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/bird2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bird2.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/bird2.imageset/bird2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipeferri/ScreenSizesSimulator/c0e29586d355583bc396e2dcf8ed9cab0e0bab64/Screen Sizes Simulator/Assets.xcassets/bird2.imageset/bird2.jpg -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/frog1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "frog1.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/frog1.imageset/frog1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipeferri/ScreenSizesSimulator/c0e29586d355583bc396e2dcf8ed9cab0e0bab64/Screen Sizes Simulator/Assets.xcassets/frog1.imageset/frog1.jpg -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/frog2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "frog2.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/frog2.imageset/frog2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipeferri/ScreenSizesSimulator/c0e29586d355583bc396e2dcf8ed9cab0e0bab64/Screen Sizes Simulator/Assets.xcassets/frog2.imageset/frog2.jpg -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/mammal1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mammal1.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/mammal1.imageset/mammal1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipeferri/ScreenSizesSimulator/c0e29586d355583bc396e2dcf8ed9cab0e0bab64/Screen Sizes Simulator/Assets.xcassets/mammal1.imageset/mammal1.jpg -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/mammal2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mammal2.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Screen Sizes Simulator/Assets.xcassets/mammal2.imageset/mammal2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipeferri/ScreenSizesSimulator/c0e29586d355583bc396e2dcf8ed9cab0e0bab64/Screen Sizes Simulator/Assets.xcassets/mammal2.imageset/mammal2.jpg -------------------------------------------------------------------------------- /Screen Sizes Simulator/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 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/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 | 47 | 63 | 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 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // Spider Experiments 4 | // 5 | // Created by Felipe Augusto Sviaghin Ferri on 29/4/17. 6 | // Copyright © 2017 Felipe Augusto Sviaghin Ferri. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | @IBDesignable 13 | extension UIView { 14 | func addSubviewWithConstraints(_ subView: UIView) { 15 | subView.translatesAutoresizingMaskIntoConstraints = false 16 | addSubview(subView) 17 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[subView]|", options: [], metrics: nil, views: ["subView":subView])) 18 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[subView]|", options: [], metrics: nil, views: ["subView":subView])) 19 | layoutIfNeeded() 20 | subView.frame = bounds 21 | } 22 | 23 | @IBInspectable var cornerRadius: CGFloat { 24 | get { 25 | return layer.cornerRadius 26 | } 27 | set { 28 | layer.cornerRadius = newValue 29 | layer.masksToBounds = newValue > 0 30 | } 31 | } 32 | 33 | @IBInspectable var borderColor: UIColor? { 34 | get { 35 | if let color = layer.borderColor { 36 | return UIColor(cgColor: color) 37 | } 38 | return nil 39 | } 40 | 41 | set { 42 | layer.borderColor = borderColor?.cgColor 43 | } 44 | } 45 | 46 | @IBInspectable var borderWidth: CGFloat { 47 | get { 48 | return layer.borderWidth 49 | } 50 | 51 | set { 52 | layer.borderWidth = borderWidth 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/SizesSimulator.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 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 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 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/SizesSimulatorViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SizesSimulatorViewController.swift 3 | // Spider Experiments 4 | // 5 | // Created by Felipe Augusto Sviaghin Ferri on 4/5/17. 6 | // Copyright © 2017 Felipe Augusto Sviaghin Ferri. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum PhoneModel { 12 | case iPhone4S, iPhone5S, iPhone6S, iPhone6SPlus 13 | } 14 | 15 | struct ScreenSize { 16 | var width: CGFloat 17 | var height: CGFloat 18 | 19 | static let iPhone4S = ScreenSize(width: 320, height: 480) 20 | static let iPhone5S = ScreenSize(width: 320, height: 568) 21 | static let iPhone6S = ScreenSize(width: 375, height: 667) 22 | static let iPhone6SPlus = ScreenSize(width: 414, height: 736) 23 | 24 | } 25 | 26 | class SizesSimulatorViewController: UIViewController { 27 | @IBOutlet weak var containerHeightLayoutConstraint: NSLayoutConstraint! 28 | @IBOutlet weak var containerWidthLayoutConstraint: NSLayoutConstraint! 29 | @IBOutlet weak var iPhoneModelSegmentedControl: UISegmentedControl! 30 | @IBOutlet weak var zoomLevelSegmentedControl: UISegmentedControl! 31 | @IBOutlet weak var containerView: UIView! 32 | @IBOutlet weak var controlPanelView: UIView! 33 | 34 | 35 | var phoneModel: PhoneModel = .iPhone6S { 36 | didSet { 37 | switch phoneModel { 38 | case .iPhone4S: 39 | screenSize = ScreenSize.iPhone4S 40 | case .iPhone5S: 41 | screenSize = ScreenSize.iPhone5S 42 | case .iPhone6S: 43 | screenSize = ScreenSize.iPhone6S 44 | case .iPhone6SPlus: 45 | screenSize = ScreenSize.iPhone6SPlus 46 | } 47 | updateUI() 48 | } 49 | } 50 | 51 | var screenSize: ScreenSize? { 52 | didSet { 53 | if let screenSize = screenSize { 54 | containerWidthLayoutConstraint.constant = screenSize.width 55 | containerHeightLayoutConstraint.constant = screenSize.height 56 | } 57 | } 58 | } 59 | @IBAction func iPhoneModelSegmentedControlValueChanged(_ sender: UISegmentedControl) { 60 | phoneModel = [PhoneModel.iPhone4S, PhoneModel.iPhone5S, PhoneModel.iPhone6S, PhoneModel.iPhone6SPlus][sender.selectedSegmentIndex] 61 | } 62 | 63 | @IBAction func zoomLevelSegmentedControlValueChanged(_ sender: UISegmentedControl) { 64 | updateUI() 65 | } 66 | 67 | func updateUI() { 68 | switch zoomLevelSegmentedControl.selectedSegmentIndex { 69 | case 0: 70 | containerView.transform = CGAffineTransform.identity 71 | case 1: 72 | containerView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0) 73 | case 2: 74 | if let screenSize = screenSize { 75 | let zoom = min(view.frame.size.height/screenSize.height, view.frame.size.width/screenSize.width) 76 | containerView.transform = CGAffineTransform(scaleX: zoom, y: zoom) 77 | } 78 | case 3: 79 | if let screenSize = screenSize { 80 | let zoom = max(view.frame.size.height/screenSize.height, view.frame.size.width/screenSize.width) 81 | containerView.transform = CGAffineTransform(scaleX: zoom, y: zoom) 82 | } 83 | default: 84 | containerView.transform = CGAffineTransform.identity 85 | } 86 | } 87 | 88 | override func viewDidLoad() { 89 | phoneModel = .iPhone6S 90 | iPhoneModelSegmentedControl.selectedSegmentIndex = 2 91 | } 92 | 93 | override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) { 94 | if motion == .motionShake { 95 | controlPanelView.isHidden = false 96 | } 97 | } 98 | @IBAction func controlPanelTap(_ sender: UITapGestureRecognizer) { 99 | controlPanelView.isHidden = true 100 | } 101 | 102 | override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 103 | if UIDevice.current.orientation.isLandscape { 104 | if let screenSize = screenSize { 105 | containerWidthLayoutConstraint.constant = screenSize.height 106 | containerHeightLayoutConstraint.constant = screenSize.width 107 | } 108 | } else { 109 | if let screenSize = screenSize { 110 | containerWidthLayoutConstraint.constant = screenSize.width 111 | containerHeightLayoutConstraint.constant = screenSize.height 112 | } 113 | } 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /Screen Sizes Simulator/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Screen Sizes Simulator 4 | // 5 | // Created by Felipe Augusto Sviaghin Ferri on 10/5/17. 6 | // Copyright © 2017 Felipe Augusto Sviaghin Ferri. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum PhotosCategory { 12 | case frogs, mammals, birds 13 | } 14 | 15 | class ViewController: UIViewController { 16 | 17 | var selectedCategory: PhotosCategory = .mammals { 18 | didSet { 19 | updateUI() 20 | } 21 | } 22 | 23 | @IBOutlet weak var photo1ImageView: UIImageView! 24 | @IBOutlet weak var photo2ImageView: UIImageView! 25 | 26 | override func viewDidLoad() { 27 | updateUI() 28 | } 29 | 30 | func updateUI() { 31 | switch selectedCategory { 32 | case .frogs: 33 | photo1ImageView.image = #imageLiteral(resourceName: "frog1") 34 | photo2ImageView.image = #imageLiteral(resourceName: "frog2") 35 | case .mammals: 36 | photo1ImageView.image = #imageLiteral(resourceName: "mammal1") 37 | photo2ImageView.image = #imageLiteral(resourceName: "mammal2") 38 | case .birds: 39 | photo1ImageView.image = #imageLiteral(resourceName: "bird1") 40 | photo2ImageView.image = #imageLiteral(resourceName: "bird2") 41 | } 42 | } 43 | 44 | @IBAction func swapButtonTap(_ sender: UIButton) { 45 | let tempImage = photo1ImageView.image 46 | photo1ImageView.image = photo2ImageView.image 47 | photo2ImageView.image = tempImage 48 | } 49 | 50 | @IBAction func frogsButtonTap(_ sender: UIButton) { 51 | selectedCategory = .frogs 52 | } 53 | 54 | @IBAction func mammalsButtonTap(_ sender: UIButton) { 55 | selectedCategory = .mammals 56 | } 57 | 58 | @IBAction func birdsButtonTap(_ sender: UIButton) { 59 | selectedCategory = .birds 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /SizesSimulator/SizesSimulator.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 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 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 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /SizesSimulator/SizesSimulatorViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SizesSimulatorViewController.swift 3 | // Spider Experiments 4 | // 5 | // Created by Felipe Augusto Sviaghin Ferri on 4/5/17. 6 | // Copyright © 2017 Felipe Augusto Sviaghin Ferri. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum PhoneModel { 12 | case iPhone4S, iPhone5S, iPhone6S, iPhone6SPlus 13 | } 14 | 15 | struct ScreenSize { 16 | var width: CGFloat 17 | var height: CGFloat 18 | 19 | static let iPhone4S = ScreenSize(width: 320, height: 480) 20 | static let iPhone5S = ScreenSize(width: 320, height: 568) 21 | static let iPhone6S = ScreenSize(width: 375, height: 667) 22 | static let iPhone6SPlus = ScreenSize(width: 414, height: 736) 23 | 24 | } 25 | 26 | class SizesSimulatorViewController: UIViewController { 27 | @IBOutlet weak var containerHeightLayoutConstraint: NSLayoutConstraint! 28 | @IBOutlet weak var containerWidthLayoutConstraint: NSLayoutConstraint! 29 | @IBOutlet weak var iPhoneModelSegmentedControl: UISegmentedControl! 30 | @IBOutlet weak var zoomLevelSegmentedControl: UISegmentedControl! 31 | @IBOutlet weak var containerView: UIView! 32 | @IBOutlet weak var controlPanelView: UIView! 33 | 34 | 35 | var phoneModel: PhoneModel = .iPhone6S { 36 | didSet { 37 | switch phoneModel { 38 | case .iPhone4S: 39 | screenSize = ScreenSize.iPhone4S 40 | case .iPhone5S: 41 | screenSize = ScreenSize.iPhone5S 42 | case .iPhone6S: 43 | screenSize = ScreenSize.iPhone6S 44 | case .iPhone6SPlus: 45 | screenSize = ScreenSize.iPhone6SPlus 46 | } 47 | updateUI() 48 | } 49 | } 50 | 51 | var screenSize: ScreenSize? { 52 | didSet { 53 | if let screenSize = screenSize { 54 | containerWidthLayoutConstraint.constant = screenSize.width 55 | containerHeightLayoutConstraint.constant = screenSize.height 56 | } 57 | } 58 | } 59 | @IBAction func iPhoneModelSegmentedControlValueChanged(_ sender: UISegmentedControl) { 60 | phoneModel = [PhoneModel.iPhone4S, PhoneModel.iPhone5S, PhoneModel.iPhone6S, PhoneModel.iPhone6SPlus][sender.selectedSegmentIndex] 61 | } 62 | 63 | @IBAction func zoomLevelSegmentedControlValueChanged(_ sender: UISegmentedControl) { 64 | updateUI() 65 | } 66 | 67 | func updateUI() { 68 | switch zoomLevelSegmentedControl.selectedSegmentIndex { 69 | case 0: 70 | containerView.transform = CGAffineTransform.identity 71 | case 1: 72 | containerView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0) 73 | case 2: 74 | if let screenSize = screenSize { 75 | let zoom = min(view.frame.size.height/screenSize.height, view.frame.size.width/screenSize.width) 76 | containerView.transform = CGAffineTransform(scaleX: zoom, y: zoom) 77 | } 78 | case 3: 79 | if let screenSize = screenSize { 80 | let zoom = max(view.frame.size.height/screenSize.height, view.frame.size.width/screenSize.width) 81 | containerView.transform = CGAffineTransform(scaleX: zoom, y: zoom) 82 | } 83 | default: 84 | containerView.transform = CGAffineTransform.identity 85 | } 86 | } 87 | 88 | override func viewDidLoad() { 89 | phoneModel = .iPhone6S 90 | iPhoneModelSegmentedControl.selectedSegmentIndex = 2 91 | } 92 | 93 | override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) { 94 | if motion == .motionShake { 95 | controlPanelView.isHidden = false 96 | } 97 | } 98 | @IBAction func controlPanelTap(_ sender: UITapGestureRecognizer) { 99 | controlPanelView.isHidden = true 100 | } 101 | 102 | override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 103 | if UIDevice.current.orientation.isLandscape { 104 | if let screenSize = screenSize { 105 | containerWidthLayoutConstraint.constant = screenSize.height 106 | containerHeightLayoutConstraint.constant = screenSize.width 107 | } 108 | } else { 109 | if let screenSize = screenSize { 110 | containerWidthLayoutConstraint.constant = screenSize.width 111 | containerHeightLayoutConstraint.constant = screenSize.height 112 | } 113 | } 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /readme_pt.md: -------------------------------------------------------------------------------- 1 | # ScreenSizesSimulator 2 | Use um único dispositivo iOS para testar seu app em todos os tamanhos de iPhone 3 | 4 | Você testa em diferentes tamanhos de tela quando está desenvolvendo seus apps? Você sabe que deveria né? 5 | 6 | Rodar o mesmo app em simuladores diferentes demora muito e ter vários dispositivos para teste é inviável para muitos de nós. É por isso que o Screen Sizes Simulator pode ser uma boa idéia para você. 7 | 8 | Screen Sizes Simulator é um storyboard de modelo e um painel de controle que te permitem rodar seu app em telas imitando todos os tamanhos de iPhone atuais. Veja nas imagens abaixo o que quero dizer. Todas as imagens foram obtidas rodando no imulador de iPhone 6 o app de demo inclído neste repositório. 9 | 10 | iPhone6 regular size | iPhone5 size on iPhone6 11 | :-------------------------:|:-------------------------: 12 | ![](/../screenshots/screenshots/iPhone6.png) | ![](/../screenshots/screenshots/iPhone5_panel.png) 13 | 14 | iPhone4 size on iPhone6 | iPhone4 size landscape 15 | :-------------------------:|:-------------------------: 16 | ![](/../screenshots/screenshots/iPhone4_panel.png) | ![](/../screenshots/screenshots/iPhone4_landscape.png) 17 | 18 | Se você executar o Screen Sizes Simulator em um iPad você pode rodar seu app em todos os tamanhos de iPhone e eles aparecerão no tamanho real do dispositivo. Talvez, como eu, você tenha um iPhone 4S e você gostaria de ver como ficaria o layout do iPhone 6. Neste caso você pode usar a opço "fit" no painel para fazer um zoom out do aplicativo até que ele encaixe na tela, mantendo as proporções dos elementos de UI. 19 | 20 | *** 21 | ## Instalando o Screen Sizes Simulator em seu app 22 | Se tiver dúvidas dá uma olhada no projeto de demo. 23 | 24 | 1. Copie a pasta "Screen Sizes" em seu projeto no Xcode. 25 | 2. Localize o seu Initial View Controller no storyboard de seu projeto e altere o Storyboard ID para "SwipeViewController" no Identity Inspector. 26 | 3. Abra o storyboard SizesSimulator e se assegure de que o bloco de Storyboard reference está apontando para o seu storyboard principal. Se você manteve o seu storyboard principal com o nome Main não precisará fazer nada. 27 | 4. Abra o target de seu projeto na aba General e mude a Main Interface para "SizesSimulator". 28 | 5. Execute seu projeto no simulador ou em um dispositivo e tudo deverá funcionar ok. 29 | 30 | Lembre-se de trocar seu Main Interface de volta para seu storyboard principal quando for lançar seu app na AppStore. Se você tiver coragem pode criar um target específico para o Screen Sizes Simulator em vez de alterar o seu target principal. No app de demo tem um exemplo disto. 31 | 32 | ## Usando o Screen Sizes Simulator 33 | O Screen Sizes Simulator tem um pequeno painel de controle no topo. Se você tocá-lo ele irá desaparecer; se você 34 | sacudir o seu dispositivo ele irá aparecer de novo. 35 | 36 | Você pode selecionar quatro tamanhos de iPhone diferentes: iPhone4S, iPhone5/SE, iPhone6S/7S, iPhone6S+/7S+. 37 | 38 | Também pode selecionar quatro níveis de zoom: 1x, 2x, fit and fill. 39 | 40 | * 1x mostra o tamanho de tela normal. Você deve usar esta opção quando for executar seu app em um dispositivo maior do que a tela que você quer mostrar (por exemplo, ao selecionar a tela de iPhone5S em um iPhone6S). 41 | * 2x mostra o dobro do tamanho da tela. Isto só é útil se você estiver rodando seu app em um iPad. É semelhante à opção de zoom que aparece quando você roda um app de iPhone (não universal) em um iPad. 42 | * fit vai aplicar um nível de zoom que encaixa a tela do app no tamanho de tela atual, mantendo as proporções. Isto é o ideal quando você quiser selecionar telas maiores do que a de seu telefone. Por exemplo para mostrar o tamanho do iPhone6S em um iPhone4S. 43 | * fill vai aplicat um nível de zoom que enche a tela com o tamanho selecionado. 44 | 45 | ## A fazer (pull requests são bem vindos) 46 | * Criar um cocoapod 47 | * Fazer uma versão do Simulador em código que não exija ficar configurando targets e info.plists. 48 | * Se você usa classes de tamanhos o simulador não irá responder corretamente em um iPad porque as classes de tamanho para altura e largura do iPad são diferentes daquelas do iPhone. Não sei como resolver este problema. 49 | --------------------------------------------------------------------------------