├── XSQLandscapeFullscreenDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── xushuangqing.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── xushuangqing.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── XSQLandscapeFullscreenDemo.xcscheme │ └── xcschememanagement.plist └── XSQLandscapeFullscreenDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json ├── first.imageset │ ├── Contents.json │ └── first.pdf ├── movie.imageset │ ├── Contents.json │ ├── movie@2x.png │ └── movie@3x.png └── second.imageset │ ├── Contents.json │ └── second.pdf ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── EnterFullscreenTransition.h ├── EnterFullscreenTransition.m ├── ExitFullscreenTransition.h ├── ExitFullscreenTransition.m ├── FirstViewController.h ├── FirstViewController.m ├── FullscreenViewController.h ├── FullscreenViewController.m ├── Info.plist ├── MovieView.h ├── MovieView.m ├── SecondViewController.h ├── SecondViewController.m ├── TabBarController.h ├── TabBarController.m ├── ThirdViewController.h ├── ThirdViewController.m └── main.m /XSQLandscapeFullscreenDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4AA34AF71E35BE7D00CC8D4C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34AF61E35BE7D00CC8D4C /* main.m */; }; 11 | 4AA34AFA1E35BE7D00CC8D4C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34AF91E35BE7D00CC8D4C /* AppDelegate.m */; }; 12 | 4AA34AFD1E35BE7D00CC8D4C /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34AFC1E35BE7D00CC8D4C /* FirstViewController.m */; }; 13 | 4AA34B001E35BE7E00CC8D4C /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34AFF1E35BE7E00CC8D4C /* SecondViewController.m */; }; 14 | 4AA34B031E35BE7E00CC8D4C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4AA34B011E35BE7E00CC8D4C /* Main.storyboard */; }; 15 | 4AA34B051E35BE7E00CC8D4C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4AA34B041E35BE7E00CC8D4C /* Assets.xcassets */; }; 16 | 4AA34B081E35BE7E00CC8D4C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4AA34B061E35BE7E00CC8D4C /* LaunchScreen.storyboard */; }; 17 | 4AA34B111E35C08D00CC8D4C /* ThirdViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34B101E35C08D00CC8D4C /* ThirdViewController.m */; }; 18 | 4AA34B141E35E1E400CC8D4C /* TabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34B131E35E1E300CC8D4C /* TabBarController.m */; }; 19 | 4AA34B171E35E4B900CC8D4C /* EnterFullscreenTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34B161E35E4B800CC8D4C /* EnterFullscreenTransition.m */; }; 20 | 4AA34B1A1E35E4CD00CC8D4C /* ExitFullscreenTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34B191E35E4CD00CC8D4C /* ExitFullscreenTransition.m */; }; 21 | 4AA34B1D1E35E4E800CC8D4C /* FullscreenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34B1C1E35E4E800CC8D4C /* FullscreenViewController.m */; }; 22 | 4AA34B201E35F5DF00CC8D4C /* MovieView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AA34B1F1E35F5DF00CC8D4C /* MovieView.m */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 4AA34AF21E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XSQLandscapeFullscreenDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 4AA34AF61E35BE7D00CC8D4C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 28 | 4AA34AF81E35BE7D00CC8D4C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 29 | 4AA34AF91E35BE7D00CC8D4C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 30 | 4AA34AFB1E35BE7D00CC8D4C /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; 31 | 4AA34AFC1E35BE7D00CC8D4C /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; 32 | 4AA34AFE1E35BE7D00CC8D4C /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; 33 | 4AA34AFF1E35BE7E00CC8D4C /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 34 | 4AA34B021E35BE7E00CC8D4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 35 | 4AA34B041E35BE7E00CC8D4C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 36 | 4AA34B071E35BE7E00CC8D4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 37 | 4AA34B091E35BE7E00CC8D4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38 | 4AA34B0F1E35C08D00CC8D4C /* ThirdViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThirdViewController.h; sourceTree = ""; }; 39 | 4AA34B101E35C08D00CC8D4C /* ThirdViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThirdViewController.m; sourceTree = ""; }; 40 | 4AA34B121E35E1E300CC8D4C /* TabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabBarController.h; sourceTree = ""; }; 41 | 4AA34B131E35E1E300CC8D4C /* TabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabBarController.m; sourceTree = ""; }; 42 | 4AA34B151E35E4B800CC8D4C /* EnterFullscreenTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnterFullscreenTransition.h; sourceTree = ""; }; 43 | 4AA34B161E35E4B800CC8D4C /* EnterFullscreenTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EnterFullscreenTransition.m; sourceTree = ""; }; 44 | 4AA34B181E35E4CD00CC8D4C /* ExitFullscreenTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExitFullscreenTransition.h; sourceTree = ""; }; 45 | 4AA34B191E35E4CD00CC8D4C /* ExitFullscreenTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExitFullscreenTransition.m; sourceTree = ""; }; 46 | 4AA34B1B1E35E4E800CC8D4C /* FullscreenViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullscreenViewController.h; sourceTree = ""; }; 47 | 4AA34B1C1E35E4E800CC8D4C /* FullscreenViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FullscreenViewController.m; sourceTree = ""; }; 48 | 4AA34B1E1E35F5DF00CC8D4C /* MovieView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MovieView.h; sourceTree = ""; }; 49 | 4AA34B1F1E35F5DF00CC8D4C /* MovieView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MovieView.m; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 4AA34AEF1E35BE7D00CC8D4C /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 4AA34AE91E35BE7D00CC8D4C = { 64 | isa = PBXGroup; 65 | children = ( 66 | 4AA34AF41E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo */, 67 | 4AA34AF31E35BE7D00CC8D4C /* Products */, 68 | ); 69 | sourceTree = ""; 70 | }; 71 | 4AA34AF31E35BE7D00CC8D4C /* Products */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 4AA34AF21E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo.app */, 75 | ); 76 | name = Products; 77 | sourceTree = ""; 78 | }; 79 | 4AA34AF41E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 4AA34B231E373A9100CC8D4C /* Third */, 83 | 4AA34B221E373A7600CC8D4C /* Second */, 84 | 4AA34B211E373A6700CC8D4C /* First */, 85 | 4AA34AF81E35BE7D00CC8D4C /* AppDelegate.h */, 86 | 4AA34AF91E35BE7D00CC8D4C /* AppDelegate.m */, 87 | 4AA34B011E35BE7E00CC8D4C /* Main.storyboard */, 88 | 4AA34B041E35BE7E00CC8D4C /* Assets.xcassets */, 89 | 4AA34B061E35BE7E00CC8D4C /* LaunchScreen.storyboard */, 90 | 4AA34B091E35BE7E00CC8D4C /* Info.plist */, 91 | 4AA34AF51E35BE7D00CC8D4C /* Supporting Files */, 92 | 4AA34B121E35E1E300CC8D4C /* TabBarController.h */, 93 | 4AA34B131E35E1E300CC8D4C /* TabBarController.m */, 94 | 4AA34B1E1E35F5DF00CC8D4C /* MovieView.h */, 95 | 4AA34B1F1E35F5DF00CC8D4C /* MovieView.m */, 96 | ); 97 | path = XSQLandscapeFullscreenDemo; 98 | sourceTree = ""; 99 | }; 100 | 4AA34AF51E35BE7D00CC8D4C /* Supporting Files */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 4AA34AF61E35BE7D00CC8D4C /* main.m */, 104 | ); 105 | name = "Supporting Files"; 106 | sourceTree = ""; 107 | }; 108 | 4AA34B211E373A6700CC8D4C /* First */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 4AA34AFB1E35BE7D00CC8D4C /* FirstViewController.h */, 112 | 4AA34AFC1E35BE7D00CC8D4C /* FirstViewController.m */, 113 | ); 114 | name = First; 115 | sourceTree = ""; 116 | }; 117 | 4AA34B221E373A7600CC8D4C /* Second */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 4AA34AFE1E35BE7D00CC8D4C /* SecondViewController.h */, 121 | 4AA34AFF1E35BE7E00CC8D4C /* SecondViewController.m */, 122 | 4AA34B151E35E4B800CC8D4C /* EnterFullscreenTransition.h */, 123 | 4AA34B161E35E4B800CC8D4C /* EnterFullscreenTransition.m */, 124 | 4AA34B181E35E4CD00CC8D4C /* ExitFullscreenTransition.h */, 125 | 4AA34B191E35E4CD00CC8D4C /* ExitFullscreenTransition.m */, 126 | 4AA34B1B1E35E4E800CC8D4C /* FullscreenViewController.h */, 127 | 4AA34B1C1E35E4E800CC8D4C /* FullscreenViewController.m */, 128 | ); 129 | name = Second; 130 | sourceTree = ""; 131 | }; 132 | 4AA34B231E373A9100CC8D4C /* Third */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 4AA34B0F1E35C08D00CC8D4C /* ThirdViewController.h */, 136 | 4AA34B101E35C08D00CC8D4C /* ThirdViewController.m */, 137 | ); 138 | name = Third; 139 | sourceTree = ""; 140 | }; 141 | /* End PBXGroup section */ 142 | 143 | /* Begin PBXNativeTarget section */ 144 | 4AA34AF11E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 4AA34B0C1E35BE7E00CC8D4C /* Build configuration list for PBXNativeTarget "XSQLandscapeFullscreenDemo" */; 147 | buildPhases = ( 148 | 4AA34AEE1E35BE7D00CC8D4C /* Sources */, 149 | 4AA34AEF1E35BE7D00CC8D4C /* Frameworks */, 150 | 4AA34AF01E35BE7D00CC8D4C /* Resources */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | ); 156 | name = XSQLandscapeFullscreenDemo; 157 | productName = XSQLandscapeFullscreenDemo; 158 | productReference = 4AA34AF21E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo.app */; 159 | productType = "com.apple.product-type.application"; 160 | }; 161 | /* End PBXNativeTarget section */ 162 | 163 | /* Begin PBXProject section */ 164 | 4AA34AEA1E35BE7D00CC8D4C /* Project object */ = { 165 | isa = PBXProject; 166 | attributes = { 167 | LastUpgradeCheck = 0820; 168 | ORGANIZATIONNAME = XSQ; 169 | TargetAttributes = { 170 | 4AA34AF11E35BE7D00CC8D4C = { 171 | CreatedOnToolsVersion = 8.2.1; 172 | DevelopmentTeam = C2TZ8VUVX6; 173 | ProvisioningStyle = Automatic; 174 | }; 175 | }; 176 | }; 177 | buildConfigurationList = 4AA34AED1E35BE7D00CC8D4C /* Build configuration list for PBXProject "XSQLandscapeFullscreenDemo" */; 178 | compatibilityVersion = "Xcode 3.2"; 179 | developmentRegion = English; 180 | hasScannedForEncodings = 0; 181 | knownRegions = ( 182 | en, 183 | Base, 184 | ); 185 | mainGroup = 4AA34AE91E35BE7D00CC8D4C; 186 | productRefGroup = 4AA34AF31E35BE7D00CC8D4C /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | 4AA34AF11E35BE7D00CC8D4C /* XSQLandscapeFullscreenDemo */, 191 | ); 192 | }; 193 | /* End PBXProject section */ 194 | 195 | /* Begin PBXResourcesBuildPhase section */ 196 | 4AA34AF01E35BE7D00CC8D4C /* Resources */ = { 197 | isa = PBXResourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 4AA34B081E35BE7E00CC8D4C /* LaunchScreen.storyboard in Resources */, 201 | 4AA34B051E35BE7E00CC8D4C /* Assets.xcassets in Resources */, 202 | 4AA34B031E35BE7E00CC8D4C /* Main.storyboard in Resources */, 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | }; 206 | /* End PBXResourcesBuildPhase section */ 207 | 208 | /* Begin PBXSourcesBuildPhase section */ 209 | 4AA34AEE1E35BE7D00CC8D4C /* Sources */ = { 210 | isa = PBXSourcesBuildPhase; 211 | buildActionMask = 2147483647; 212 | files = ( 213 | 4AA34B001E35BE7E00CC8D4C /* SecondViewController.m in Sources */, 214 | 4AA34B201E35F5DF00CC8D4C /* MovieView.m in Sources */, 215 | 4AA34B111E35C08D00CC8D4C /* ThirdViewController.m in Sources */, 216 | 4AA34AFA1E35BE7D00CC8D4C /* AppDelegate.m in Sources */, 217 | 4AA34B171E35E4B900CC8D4C /* EnterFullscreenTransition.m in Sources */, 218 | 4AA34B141E35E1E400CC8D4C /* TabBarController.m in Sources */, 219 | 4AA34B1A1E35E4CD00CC8D4C /* ExitFullscreenTransition.m in Sources */, 220 | 4AA34AFD1E35BE7D00CC8D4C /* FirstViewController.m in Sources */, 221 | 4AA34B1D1E35E4E800CC8D4C /* FullscreenViewController.m in Sources */, 222 | 4AA34AF71E35BE7D00CC8D4C /* main.m in Sources */, 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | }; 226 | /* End PBXSourcesBuildPhase section */ 227 | 228 | /* Begin PBXVariantGroup section */ 229 | 4AA34B011E35BE7E00CC8D4C /* Main.storyboard */ = { 230 | isa = PBXVariantGroup; 231 | children = ( 232 | 4AA34B021E35BE7E00CC8D4C /* Base */, 233 | ); 234 | name = Main.storyboard; 235 | sourceTree = ""; 236 | }; 237 | 4AA34B061E35BE7E00CC8D4C /* LaunchScreen.storyboard */ = { 238 | isa = PBXVariantGroup; 239 | children = ( 240 | 4AA34B071E35BE7E00CC8D4C /* Base */, 241 | ); 242 | name = LaunchScreen.storyboard; 243 | sourceTree = ""; 244 | }; 245 | /* End PBXVariantGroup section */ 246 | 247 | /* Begin XCBuildConfiguration section */ 248 | 4AA34B0A1E35BE7E00CC8D4C /* Debug */ = { 249 | isa = XCBuildConfiguration; 250 | buildSettings = { 251 | ALWAYS_SEARCH_USER_PATHS = NO; 252 | CLANG_ANALYZER_NONNULL = YES; 253 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 254 | CLANG_CXX_LIBRARY = "libc++"; 255 | CLANG_ENABLE_MODULES = YES; 256 | CLANG_ENABLE_OBJC_ARC = YES; 257 | CLANG_WARN_BOOL_CONVERSION = YES; 258 | CLANG_WARN_CONSTANT_CONVERSION = YES; 259 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 260 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 261 | CLANG_WARN_EMPTY_BODY = YES; 262 | CLANG_WARN_ENUM_CONVERSION = YES; 263 | CLANG_WARN_INFINITE_RECURSION = YES; 264 | CLANG_WARN_INT_CONVERSION = YES; 265 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 266 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 267 | CLANG_WARN_UNREACHABLE_CODE = YES; 268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 269 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = dwarf; 272 | ENABLE_STRICT_OBJC_MSGSEND = YES; 273 | ENABLE_TESTABILITY = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_DYNAMIC_NO_PIC = NO; 276 | GCC_NO_COMMON_BLOCKS = YES; 277 | GCC_OPTIMIZATION_LEVEL = 0; 278 | GCC_PREPROCESSOR_DEFINITIONS = ( 279 | "DEBUG=1", 280 | "$(inherited)", 281 | ); 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 284 | GCC_WARN_UNDECLARED_SELECTOR = YES; 285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 286 | GCC_WARN_UNUSED_FUNCTION = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 289 | MTL_ENABLE_DEBUG_INFO = YES; 290 | ONLY_ACTIVE_ARCH = YES; 291 | SDKROOT = iphoneos; 292 | TARGETED_DEVICE_FAMILY = "1,2"; 293 | }; 294 | name = Debug; 295 | }; 296 | 4AA34B0B1E35BE7E00CC8D4C /* Release */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | ALWAYS_SEARCH_USER_PATHS = NO; 300 | CLANG_ANALYZER_NONNULL = YES; 301 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 302 | CLANG_CXX_LIBRARY = "libc++"; 303 | CLANG_ENABLE_MODULES = YES; 304 | CLANG_ENABLE_OBJC_ARC = YES; 305 | CLANG_WARN_BOOL_CONVERSION = YES; 306 | CLANG_WARN_CONSTANT_CONVERSION = YES; 307 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 308 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 309 | CLANG_WARN_EMPTY_BODY = YES; 310 | CLANG_WARN_ENUM_CONVERSION = YES; 311 | CLANG_WARN_INFINITE_RECURSION = YES; 312 | CLANG_WARN_INT_CONVERSION = YES; 313 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 314 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 315 | CLANG_WARN_UNREACHABLE_CODE = YES; 316 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 317 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 318 | COPY_PHASE_STRIP = NO; 319 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 320 | ENABLE_NS_ASSERTIONS = NO; 321 | ENABLE_STRICT_OBJC_MSGSEND = YES; 322 | GCC_C_LANGUAGE_STANDARD = gnu99; 323 | GCC_NO_COMMON_BLOCKS = YES; 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 331 | MTL_ENABLE_DEBUG_INFO = NO; 332 | SDKROOT = iphoneos; 333 | TARGETED_DEVICE_FAMILY = "1,2"; 334 | VALIDATE_PRODUCT = YES; 335 | }; 336 | name = Release; 337 | }; 338 | 4AA34B0D1E35BE7E00CC8D4C /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 342 | DEVELOPMENT_TEAM = C2TZ8VUVX6; 343 | INFOPLIST_FILE = XSQLandscapeFullscreenDemo/Info.plist; 344 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 345 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 346 | PRODUCT_BUNDLE_IDENTIFIER = xsq.XSQLandscapeFullscreenDemo2; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | }; 349 | name = Debug; 350 | }; 351 | 4AA34B0E1E35BE7E00CC8D4C /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 355 | DEVELOPMENT_TEAM = C2TZ8VUVX6; 356 | INFOPLIST_FILE = XSQLandscapeFullscreenDemo/Info.plist; 357 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 358 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 359 | PRODUCT_BUNDLE_IDENTIFIER = xsq.XSQLandscapeFullscreenDemo2; 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | }; 362 | name = Release; 363 | }; 364 | /* End XCBuildConfiguration section */ 365 | 366 | /* Begin XCConfigurationList section */ 367 | 4AA34AED1E35BE7D00CC8D4C /* Build configuration list for PBXProject "XSQLandscapeFullscreenDemo" */ = { 368 | isa = XCConfigurationList; 369 | buildConfigurations = ( 370 | 4AA34B0A1E35BE7E00CC8D4C /* Debug */, 371 | 4AA34B0B1E35BE7E00CC8D4C /* Release */, 372 | ); 373 | defaultConfigurationIsVisible = 0; 374 | defaultConfigurationName = Release; 375 | }; 376 | 4AA34B0C1E35BE7E00CC8D4C /* Build configuration list for PBXNativeTarget "XSQLandscapeFullscreenDemo" */ = { 377 | isa = XCConfigurationList; 378 | buildConfigurations = ( 379 | 4AA34B0D1E35BE7E00CC8D4C /* Debug */, 380 | 4AA34B0E1E35BE7E00CC8D4C /* Release */, 381 | ); 382 | defaultConfigurationIsVisible = 0; 383 | defaultConfigurationName = Release; 384 | }; 385 | /* End XCConfigurationList section */ 386 | }; 387 | rootObject = 4AA34AEA1E35BE7D00CC8D4C /* Project object */; 388 | } 389 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo.xcodeproj/project.xcworkspace/xcuserdata/xushuangqing.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xushuangqing/XSQLandscapeFullscreenDemo/28f05431e5143fa73fb54ba6b9cefa3b281be709/XSQLandscapeFullscreenDemo.xcodeproj/project.xcworkspace/xcuserdata/xushuangqing.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo.xcodeproj/xcuserdata/xushuangqing.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 56 | 68 | 69 | 70 | 72 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo.xcodeproj/xcuserdata/xushuangqing.xcuserdatad/xcschemes/XSQLandscapeFullscreenDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo.xcodeproj/xcuserdata/xushuangqing.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | XSQLandscapeFullscreenDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 4AA34AF11E35BE7D00CC8D4C 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/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 | } -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/first.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "first.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/first.imageset/first.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xushuangqing/XSQLandscapeFullscreenDemo/28f05431e5143fa73fb54ba6b9cefa3b281be709/XSQLandscapeFullscreenDemo/Assets.xcassets/first.imageset/first.pdf -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/movie.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "movie@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "movie@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/movie.imageset/movie@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xushuangqing/XSQLandscapeFullscreenDemo/28f05431e5143fa73fb54ba6b9cefa3b281be709/XSQLandscapeFullscreenDemo/Assets.xcassets/movie.imageset/movie@2x.png -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/movie.imageset/movie@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xushuangqing/XSQLandscapeFullscreenDemo/28f05431e5143fa73fb54ba6b9cefa3b281be709/XSQLandscapeFullscreenDemo/Assets.xcassets/movie.imageset/movie@3x.png -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "second.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/Assets.xcassets/second.imageset/second.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xushuangqing/XSQLandscapeFullscreenDemo/28f05431e5143fa73fb54ba6b9cefa3b281be709/XSQLandscapeFullscreenDemo/Assets.xcassets/second.imageset/second.pdf -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/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 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/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 | 31 | 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 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 131 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/EnterFullscreenTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // EnterFullscreenTransition.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | @class MovieView; 11 | 12 | @interface EnterFullscreenTransition : NSObject 13 | 14 | - (instancetype)initWithMovieView:(MovieView *)movieView; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/EnterFullscreenTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // EnterFullscreenTransition.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "EnterFullscreenTransition.h" 10 | #import "MovieView.h" 11 | 12 | @interface EnterFullscreenTransition () 13 | 14 | @property (nonatomic, strong) UIView *movieView; 15 | 16 | @end 17 | 18 | @implementation EnterFullscreenTransition 19 | 20 | - (instancetype)initWithMovieView:(MovieView *)movieView { 21 | self = [super init]; 22 | if (self) { 23 | _movieView = movieView; 24 | } 25 | return self; 26 | } 27 | 28 | - (NSTimeInterval)transitionDuration:(nullable id )transitionContext { 29 | return 0.5; 30 | } 31 | 32 | - (void)animateTransition:(id )transitionContext { 33 | UIViewController *presentedViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 34 | UIView *presentedView = nil; 35 | if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { 36 | presentedView = presentedViewController.view; 37 | } 38 | else { 39 | presentedView = [transitionContext viewForKey:UITransitionContextToViewKey]; 40 | } 41 | 42 | CGRect smallMovieFrame = [[transitionContext containerView] convertRect:self.movieView.bounds fromView:self.movieView]; 43 | 44 | if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { 45 | 46 | CGPoint centerAfterPresented = [transitionContext containerView].center; 47 | CGRect presentedViewFinalBounds = CGRectMake(0, 0, CGRectGetHeight([transitionContext containerView].bounds), CGRectGetWidth([transitionContext containerView].bounds)); 48 | 49 | presentedView.bounds = self.movieView.bounds; 50 | presentedView.center = CGPointMake(CGRectGetMidX(smallMovieFrame), CGRectGetMidY(smallMovieFrame)); 51 | [[transitionContext containerView] addSubview:presentedView]; 52 | presentedView.transform = CGAffineTransformIdentity; 53 | 54 | /* 55 | * 将movieView放入presentedView中 56 | */ 57 | self.movieView.frame = presentedView.bounds; 58 | [presentedView addSubview:self.movieView]; 59 | 60 | if ([transitionContext isAnimated]) { 61 | [UIView animateWithDuration:[self transitionDuration:transitionContext] 62 | delay:0.0 63 | options:UIViewAnimationOptionLayoutSubviews 64 | animations:^{ 65 | /** 66 | * iOS7中,屏幕旋转后,window.size不会变化,整个presentedView需要手工旋转 67 | */ 68 | presentedView.bounds = presentedViewFinalBounds; 69 | presentedView.center = centerAfterPresented; 70 | presentedView.transform = CGAffineTransformMakeRotation(-M_PI_2); 71 | self.movieView.frame = presentedView.bounds; 72 | } 73 | completion:^(BOOL finished) { 74 | [transitionContext completeTransition:YES]; 75 | }]; 76 | } 77 | } 78 | else { 79 | /* 80 | * 先将presentedView变成小屏的大小 81 | */ 82 | presentedView.bounds = self.movieView.bounds; 83 | presentedView.transform = CGAffineTransformMakeRotation(M_PI_2); 84 | presentedView.center = CGPointMake(CGRectGetMidX(smallMovieFrame), CGRectGetMidY(smallMovieFrame)); 85 | [[transitionContext containerView] addSubview:presentedView]; 86 | 87 | /* 88 | * 将movieView放入presentedView中 89 | */ 90 | self.movieView.frame = presentedView.bounds; 91 | [presentedView addSubview:self.movieView]; 92 | 93 | /* 94 | * presentedView在动画中变为finalFrame 95 | */ 96 | CGRect presentedViewFinalFrame = [transitionContext finalFrameForViewController:presentedViewController]; 97 | [UIView animateWithDuration:[self transitionDuration:transitionContext] 98 | delay:0.0 options:UIViewAnimationOptionLayoutSubviews 99 | animations:^{ 100 | presentedView.transform = CGAffineTransformIdentity; 101 | presentedView.frame = presentedViewFinalFrame; 102 | self.movieView.frame = presentedView.bounds; 103 | } 104 | completion:^(BOOL finished) { 105 | [transitionContext completeTransition:YES]; 106 | }]; 107 | } 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/ExitFullscreenTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExitFullscreenTransition.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | @class MovieView; 11 | 12 | @interface ExitFullscreenTransition : NSObject 13 | 14 | - (instancetype)initWithMovieView:(MovieView *)movieView; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/ExitFullscreenTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExitFullscreenTransition.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "ExitFullscreenTransition.h" 10 | #import "MovieView.h" 11 | 12 | @interface ExitFullscreenTransition () 13 | 14 | @property (nonatomic, strong) MovieView *movieView; 15 | 16 | @end 17 | 18 | @implementation ExitFullscreenTransition 19 | 20 | - (instancetype)initWithMovieView:(MovieView *)movieView { 21 | self = [super init]; 22 | if (self) { 23 | _movieView = movieView; 24 | } 25 | return self; 26 | } 27 | 28 | - (NSTimeInterval)transitionDuration:(nullable id )transitionContext { 29 | return 0.5; 30 | } 31 | 32 | - (void)animateTransition:(id )transitionContext { 33 | UIViewController *dismissingViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 34 | UIView *dismissingView = nil; 35 | if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { 36 | dismissingView = dismissingViewController.view; 37 | } 38 | else { 39 | dismissingView = [transitionContext viewForKey:UITransitionContextFromViewKey]; 40 | } 41 | 42 | CGRect smallMovieFrame = [[transitionContext containerView] convertRect:self.movieView.movieViewFrame fromView:self.movieView.movieViewParentView]; 43 | [UIView animateWithDuration:[self transitionDuration:transitionContext] 44 | delay:0.0 45 | options:UIViewAnimationOptionLayoutSubviews 46 | animations:^{ 47 | dismissingView.transform = CGAffineTransformIdentity; 48 | dismissingView.frame = smallMovieFrame; 49 | self.movieView.frame = dismissingView.bounds; 50 | } 51 | completion:^(BOOL finished) { 52 | self.movieView.frame = self.movieView.movieViewFrame; 53 | [self.movieView.movieViewParentView addSubview:self.movieView]; 54 | [dismissingView removeFromSuperview]; 55 | [transitionContext completeTransition:YES]; 56 | }]; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/FirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FirstViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/FirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "FirstViewController.h" 10 | #import "MovieView.h" 11 | 12 | 13 | @interface FirstViewController () 14 | 15 | @property (nonatomic, strong) MovieView *movieView; 16 | 17 | @end 18 | 19 | @implementation FirstViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.movieView = [[MovieView alloc] init]; 25 | self.movieView.userInteractionEnabled = YES; 26 | self.movieView.frame = CGRectMake(0, 100, 320, 180); 27 | [self.view addSubview:self.movieView]; 28 | 29 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; 30 | [self.movieView addGestureRecognizer:tapGestureRecognizer]; 31 | } 32 | 33 | - (void)handleTapGesture:(UITapGestureRecognizer *)sender { 34 | if (sender.state == UIGestureRecognizerStateEnded) { 35 | if (self.movieView.state == MovieViewStateSmall) { 36 | [self enterFullscreen]; 37 | } 38 | else if (self.movieView.state == MovieViewStateFullscreen) { 39 | [self exitFullscreen]; 40 | } 41 | } 42 | } 43 | 44 | - (void)enterFullscreen { 45 | 46 | if (self.movieView.state != MovieViewStateSmall) { 47 | return; 48 | } 49 | 50 | self.movieView.state = MovieViewStateAnimating; 51 | 52 | /* 53 | * 记录进入全屏前的parentView和frame 54 | */ 55 | self.movieView.movieViewParentView = self.movieView.superview; 56 | self.movieView.movieViewFrame = self.movieView.frame; 57 | 58 | /* 59 | * movieView移到window上 60 | */ 61 | CGRect rectInWindow = [self.movieView convertRect:self.movieView.bounds toView:[UIApplication sharedApplication].keyWindow]; 62 | [self.movieView removeFromSuperview]; 63 | self.movieView.frame = rectInWindow; 64 | [[UIApplication sharedApplication].keyWindow addSubview:self.movieView]; 65 | 66 | /* 67 | * 执行动画 68 | */ 69 | [UIView animateWithDuration:0.5 animations:^{ 70 | self.movieView.transform = CGAffineTransformMakeRotation(M_PI_2); 71 | self.movieView.bounds = CGRectMake(0, 0, CGRectGetHeight(self.movieView.superview.bounds), CGRectGetWidth(self.movieView.superview.bounds)); 72 | self.movieView.center = CGPointMake(CGRectGetMidX(self.movieView.superview.bounds), CGRectGetMidY(self.movieView.superview.bounds)); 73 | } completion:^(BOOL finished) { 74 | self.movieView.state = MovieViewStateFullscreen; 75 | }]; 76 | } 77 | 78 | - (void)exitFullscreen { 79 | 80 | if (self.movieView.state != MovieViewStateFullscreen) { 81 | return; 82 | } 83 | 84 | self.movieView.state = MovieViewStateAnimating; 85 | 86 | CGRect frame = [self.movieView.movieViewParentView convertRect:self.movieView.movieViewFrame toView:[UIApplication sharedApplication].keyWindow]; 87 | [UIView animateWithDuration:0.5 animations:^{ 88 | self.movieView.transform = CGAffineTransformIdentity; 89 | self.movieView.frame = frame; 90 | } completion:^(BOOL finished) { 91 | /* 92 | * movieView回到小屏位置 93 | */ 94 | [self.movieView removeFromSuperview]; 95 | self.movieView.frame = self.movieView.movieViewFrame; 96 | [self.movieView.movieViewParentView addSubview:self.movieView]; 97 | self.movieView.state = MovieViewStateSmall; 98 | }]; 99 | } 100 | 101 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { 102 | return UIInterfaceOrientationMaskPortrait; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/FullscreenViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FullscreenViewController.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FullscreenViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/FullscreenViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FullscreenViewController.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "FullscreenViewController.h" 10 | 11 | @interface FullscreenViewController () 12 | 13 | @end 14 | 15 | @implementation FullscreenViewController 16 | 17 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { 18 | return UIInterfaceOrientationMaskLandscapeLeft; 19 | } 20 | 21 | - (BOOL)prefersStatusBarHidden { 22 | return NO; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/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 | UIStatusBarTintParameters 32 | 33 | UINavigationBar 34 | 35 | Style 36 | UIBarStyleDefault 37 | Translucent 38 | 39 | 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | UISupportedInterfaceOrientations~ipad 48 | 49 | UIInterfaceOrientationPortrait 50 | UIInterfaceOrientationPortraitUpsideDown 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/MovieView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MovieView.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, MovieViewState) { 12 | MovieViewStateSmall, 13 | MovieViewStateAnimating, 14 | MovieViewStateFullscreen, 15 | }; 16 | 17 | @interface MovieView : UIImageView 18 | 19 | /** 20 | 记录小屏时的parentView 21 | */ 22 | @property (nonatomic, weak) UIView *movieViewParentView; 23 | 24 | /** 25 | 记录小屏时的frame 26 | */ 27 | @property (nonatomic, assign) CGRect movieViewFrame; 28 | 29 | @property (nonatomic, assign) MovieViewState state; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/MovieView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MovieView.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "MovieView.h" 10 | 11 | @implementation MovieView 12 | 13 | - (instancetype)init { 14 | self = [super init]; 15 | if (self) { 16 | self.image = [UIImage imageNamed:@"movie"]; 17 | } 18 | return self; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SecondViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | #import "EnterFullscreenTransition.h" 11 | #import "ExitFullscreenTransition.h" 12 | #import "FullscreenViewController.h" 13 | #import "MovieView.h" 14 | 15 | @interface SecondViewController () 16 | 17 | @property (nonatomic, strong) MovieView *movieView; 18 | @property (nonatomic, strong) FullscreenViewController *fullscreenViewController; 19 | 20 | @property (nonatomic, strong) UILabel *buggyLabel; 21 | 22 | @end 23 | 24 | @implementation SecondViewController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | 29 | self.movieView = [[MovieView alloc] init]; 30 | self.movieView.userInteractionEnabled = YES; 31 | self.movieView.frame = CGRectMake(0, 100, 320, 180); 32 | [self.view addSubview:self.movieView]; 33 | 34 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; 35 | [self.movieView addGestureRecognizer:tapGestureRecognizer]; 36 | 37 | self.buggyLabel = [[UILabel alloc] init]; 38 | self.buggyLabel.text = @"示例:通过读取window的长宽来布局会导致动画过程中布局异常"; 39 | self.buggyLabel.numberOfLines = 0; 40 | self.buggyLabel.textColor = [UIColor redColor]; 41 | [self.view addSubview:self.buggyLabel]; 42 | } 43 | 44 | - (void)viewWillLayoutSubviews { 45 | [super viewWillLayoutSubviews]; 46 | 47 | CGFloat width = [UIApplication sharedApplication].keyWindow.bounds.size.width / 2.0; 48 | self.buggyLabel.frame = CGRectMake(0, 400, width, 200); 49 | } 50 | 51 | - (void)handleTapGesture:(UITapGestureRecognizer *)sender { 52 | if (sender.state == UIGestureRecognizerStateEnded) { 53 | if (self.movieView.state == MovieViewStateSmall) { 54 | [self enterFullscreen]; 55 | } 56 | else if (self.movieView.state == MovieViewStateFullscreen) { 57 | [self exitFullscreen]; 58 | } 59 | } 60 | } 61 | 62 | - (void)enterFullscreen { 63 | 64 | if (self.movieView.state != MovieViewStateSmall) { 65 | return; 66 | } 67 | 68 | self.movieView.state = MovieViewStateAnimating; 69 | 70 | self.movieView.movieViewFrame = self.movieView.frame; 71 | self.movieView.movieViewParentView = self.movieView.superview; 72 | 73 | FullscreenViewController *fullscreenViewController = [[FullscreenViewController alloc] init]; 74 | if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { 75 | fullscreenViewController.modalPresentationStyle = UIModalPresentationOverFullScreen; 76 | } 77 | else { 78 | fullscreenViewController.modalPresentationStyle = UIModalPresentationCustom; 79 | } 80 | fullscreenViewController.transitioningDelegate = self; 81 | fullscreenViewController.modalPresentationCapturesStatusBarAppearance = true; 82 | [self presentViewController:fullscreenViewController animated:YES completion:^{ 83 | self.movieView.state = MovieViewStateFullscreen; 84 | }]; 85 | self.fullscreenViewController = fullscreenViewController; 86 | } 87 | 88 | - (void)exitFullscreen { 89 | 90 | if (self.movieView.state != MovieViewStateFullscreen) { 91 | return; 92 | } 93 | 94 | self.movieView.state = MovieViewStateAnimating; 95 | [self.fullscreenViewController dismissViewControllerAnimated:YES completion:^{ 96 | self.movieView.state = MovieViewStateSmall; 97 | }]; 98 | } 99 | 100 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { 101 | return UIInterfaceOrientationMaskPortrait; 102 | } 103 | 104 | #pragma mark - UIViewControllerTransitioningDelegate 105 | 106 | - (nullable id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { 107 | return [[EnterFullscreenTransition alloc] initWithMovieView:self.movieView]; 108 | } 109 | 110 | - (nullable id )animationControllerForDismissedController:(UIViewController *)dismissed { 111 | return [[ExitFullscreenTransition alloc] initWithMovieView:self.movieView]; 112 | } 113 | 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/TabBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TabBarController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/TabBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "TabBarController.h" 10 | 11 | @interface TabBarController () 12 | 13 | @end 14 | 15 | @implementation TabBarController 16 | 17 | - (BOOL)shouldAutorotate { 18 | return [self.selectedViewController shouldAutorotate]; 19 | } 20 | 21 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { 22 | return [self.selectedViewController supportedInterfaceOrientations]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/ThirdViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.h 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ThirdViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/ThirdViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import "ThirdViewController.h" 10 | #import "MovieView.h" 11 | 12 | @interface ThirdViewController () 13 | 14 | @property (nonatomic, strong) MovieView *movieView; 15 | 16 | @end 17 | 18 | @implementation ThirdViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | self.movieView = [[MovieView alloc] init]; 24 | self.movieView.userInteractionEnabled = YES; 25 | self.movieView.frame = CGRectMake(0, 100, 320, 180); 26 | [self.view addSubview:self.movieView]; 27 | 28 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; 29 | [self.movieView addGestureRecognizer:tapGestureRecognizer]; 30 | } 31 | 32 | - (void)viewDidAppear:(BOOL)animated { 33 | [super viewDidAppear:animated]; 34 | } 35 | 36 | - (void)handleTapGesture:(UITapGestureRecognizer *)sender { 37 | if (sender.state == UIGestureRecognizerStateEnded) { 38 | if (self.movieView.state == MovieViewStateSmall) { 39 | [self enterFullscreen]; 40 | } 41 | else if (self.movieView.state == MovieViewStateFullscreen) { 42 | [self exitFullscreen]; 43 | } 44 | } 45 | } 46 | 47 | - (void)enterFullscreen { 48 | 49 | if (self.movieView.state != MovieViewStateSmall) { 50 | return; 51 | } 52 | 53 | self.movieView.state = MovieViewStateAnimating; 54 | 55 | /* 56 | * 记录进入全屏前的parentView和frame 57 | */ 58 | self.movieView.movieViewParentView = self.movieView.superview; 59 | self.movieView.movieViewFrame = self.movieView.frame; 60 | 61 | /* 62 | * movieView移到window上 63 | */ 64 | CGRect rectInWindow = [self.movieView convertRect:self.movieView.bounds toView:[UIApplication sharedApplication].keyWindow]; 65 | [self.movieView removeFromSuperview]; 66 | self.movieView.frame = rectInWindow; 67 | [[UIApplication sharedApplication].keyWindow addSubview:self.movieView]; 68 | 69 | /* 70 | * 执行动画 71 | */ 72 | [UIView animateWithDuration:0.5 animations:^{ 73 | self.movieView.transform = CGAffineTransformMakeRotation(M_PI_2); 74 | self.movieView.bounds = CGRectMake(0, 0, CGRectGetHeight(self.movieView.superview.bounds), CGRectGetWidth(self.movieView.superview.bounds)); 75 | self.movieView.center = CGPointMake(CGRectGetMidX(self.movieView.superview.bounds), CGRectGetMidY(self.movieView.superview.bounds)); 76 | } completion:^(BOOL finished) { 77 | self.movieView.state = MovieViewStateFullscreen; 78 | }]; 79 | 80 | [self refreshStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; 81 | } 82 | 83 | - (void)exitFullscreen { 84 | 85 | if (self.movieView.state != MovieViewStateFullscreen) { 86 | return; 87 | } 88 | 89 | self.movieView.state = MovieViewStateAnimating; 90 | 91 | CGRect frame = [self.movieView.movieViewParentView convertRect:self.movieView.movieViewFrame toView:[UIApplication sharedApplication].keyWindow]; 92 | [UIView animateWithDuration:0.5 animations:^{ 93 | self.movieView.transform = CGAffineTransformIdentity; 94 | self.movieView.frame = frame; 95 | } completion:^(BOOL finished) { 96 | /* 97 | * movieView回到小屏位置 98 | */ 99 | [self.movieView removeFromSuperview]; 100 | self.movieView.frame = self.movieView.movieViewFrame; 101 | [self.movieView.movieViewParentView addSubview:self.movieView]; 102 | self.movieView.state = MovieViewStateSmall; 103 | }]; 104 | 105 | [self refreshStatusBarOrientation:UIInterfaceOrientationPortrait]; 106 | } 107 | 108 | - (void)refreshStatusBarOrientation:(UIInterfaceOrientation)interfaceOrientation { 109 | [[UIApplication sharedApplication] setStatusBarOrientation:interfaceOrientation animated:YES]; 110 | } 111 | 112 | - (BOOL)shouldAutorotate { 113 | return NO; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /XSQLandscapeFullscreenDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XSQLandscapeFullscreenDemo 4 | // 5 | // Created by 徐霜晴 on 17/1/23. 6 | // Copyright © 2017年 XSQ. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------