├── .gitignore ├── AHKNavigationController.podspec ├── Classes ├── AHKNavigationController.h └── AHKNavigationController.m ├── Example ├── AHKNavigationController.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── AHKNavigationController │ ├── AHKAppDelegate.h │ ├── AHKAppDelegate.m │ ├── AHKNavigationController-Info.plist │ ├── AHKNavigationController-Prefix.pch │ ├── AHKTestViewController.h │ ├── AHKTestViewController.m │ ├── AHKTestViewController.xib │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── Podfile ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pbxuser 3 | !default.pbxuser 4 | *.mode1v3 5 | !default.mode1v3 6 | *.mode2v3 7 | !default.mode2v3 8 | *.perspectivev3 9 | !default.perspectivev3 10 | xcuserdata 11 | *.xccheckout 12 | *.moved-aside 13 | DerivedData 14 | *.hmap 15 | *.ipa 16 | 17 | Pods/ 18 | Example/Podfile.lock 19 | Example/AHKNavigationController.xcworkspace/contents.xcworkspacedata 20 | Rakefile -------------------------------------------------------------------------------- /AHKNavigationController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "AHKNavigationController" 3 | s.version = "1.3" 4 | s.summary = "A UINavigationController subclass allowing the interactive pop gesture when the navigation bar is hidden or a custom back button is used." 5 | 6 | s.homepage = "https://github.com/fastred/AHKNavigationController" 7 | s.license = { :type => "MIT", :file => "LICENSE" } 8 | 9 | s.authors = { "Arkadiusz Holko" => "fastred@fastred.org" } 10 | 11 | s.platform = :ios, "7.0" 12 | s.ios.deployment_target = '7.0' 13 | s.source = { :git => "https://github.com/fastred/AHKNavigationController.git", :tag => s.version.to_s } 14 | 15 | s.source_files = 'Classes' 16 | s.public_header_files = 'Classes/*.h' 17 | s.requires_arc = true 18 | end 19 | -------------------------------------------------------------------------------- /Classes/AHKNavigationController.h: -------------------------------------------------------------------------------- 1 | // Created by Arkadiusz on 01-04-14. 2 | 3 | #import 4 | 5 | /// A UINavigationController subclass allowing the interactive pop gesture to be recognized when the navigation bar is hidden or a custom back button is used. 6 | @interface AHKNavigationController : UINavigationController 7 | 8 | - (void)pushViewController:(UIViewController *)viewController 9 | animated:(BOOL)animated __attribute__((objc_requires_super)); 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Classes/AHKNavigationController.m: -------------------------------------------------------------------------------- 1 | // Created by Arkadiusz on 01-04-14. 2 | 3 | #import "AHKNavigationController.h" 4 | 5 | @interface AHKNavigationController () 6 | /// A Boolean value indicating whether navigation controller is currently pushing a new view controller on the stack. 7 | @property (nonatomic, getter = isDuringPushAnimation) BOOL duringPushAnimation; 8 | /// A real delegate of the class. `delegate` property is used only for keeping an internal state during 9 | /// animations – we need to know when the animation ended, and that info is available only 10 | /// from `navigationController:didShowViewController:animated:`. 11 | @property (weak, nonatomic) id realDelegate; 12 | @end 13 | 14 | @implementation AHKNavigationController 15 | 16 | #pragma mark - NSObject 17 | 18 | - (void)dealloc 19 | { 20 | self.delegate = nil; 21 | self.interactivePopGestureRecognizer.delegate = nil; 22 | } 23 | 24 | #pragma mark - UIViewController 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | 30 | if (!self.delegate) { 31 | self.delegate = self; 32 | } 33 | 34 | self.interactivePopGestureRecognizer.delegate = self; 35 | } 36 | 37 | #pragma mark - UINavigationController 38 | 39 | - (void)setDelegate:(id)delegate 40 | { 41 | self.realDelegate = delegate != self ? delegate : nil; 42 | [super setDelegate:delegate ? self : nil]; 43 | } 44 | 45 | - (void)pushViewController:(UIViewController *)viewController 46 | animated:(BOOL)animated __attribute__((objc_requires_super)) 47 | { 48 | self.duringPushAnimation = YES; 49 | [super pushViewController:viewController animated:animated]; 50 | } 51 | 52 | #pragma mark UINavigationControllerDelegate 53 | 54 | - (void)navigationController:(UINavigationController *)navigationController 55 | didShowViewController:(UIViewController *)viewController 56 | animated:(BOOL)animated 57 | { 58 | NSCAssert(self.interactivePopGestureRecognizer.delegate == self, @"AHKNavigationController won't work correctly if you change interactivePopGestureRecognizer's delegate."); 59 | 60 | self.duringPushAnimation = NO; 61 | 62 | if ([self.realDelegate respondsToSelector:_cmd]) { 63 | [self.realDelegate navigationController:navigationController didShowViewController:viewController animated:animated]; 64 | } 65 | } 66 | 67 | #pragma mark - UIGestureRecognizerDelegate 68 | 69 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 70 | { 71 | if (gestureRecognizer == self.interactivePopGestureRecognizer) { 72 | // Disable pop gesture in two situations: 73 | // 1) when the pop animation is in progress 74 | // 2) when user swipes quickly a couple of times and animations don't have time to be performed 75 | return [self.viewControllers count] > 1 && !self.isDuringPushAnimation; 76 | } else { 77 | // default value 78 | return YES; 79 | } 80 | } 81 | 82 | #pragma mark - Delegate Forwarder 83 | 84 | // Thanks for the idea goes to: https://github.com/steipete/PSPDFTextView/blob/ee9ce04ad04217efe0bc84d67f3895a34252d37c/PSPDFTextView/PSPDFTextView.m#L148-164 85 | 86 | - (BOOL)respondsToSelector:(SEL)s 87 | { 88 | return [super respondsToSelector:s] || [self.realDelegate respondsToSelector:s]; 89 | } 90 | 91 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)s 92 | { 93 | return [super methodSignatureForSelector:s] ?: [(id)self.realDelegate methodSignatureForSelector:s]; 94 | } 95 | 96 | - (void)forwardInvocation:(NSInvocation *)invocation 97 | { 98 | id delegate = self.realDelegate; 99 | if ([delegate respondsToSelector:invocation.selector]) { 100 | [invocation invokeWithTarget:delegate]; 101 | } 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /Example/AHKNavigationController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | archiveVersion 6 | 1 7 | classes 8 | 9 | objectVersion 10 | 46 11 | objects 12 | 13 | 130781B44ACA453CA2FA6234 14 | 15 | buildActionMask 16 | 2147483647 17 | files 18 | 19 | inputPaths 20 | 21 | isa 22 | PBXShellScriptBuildPhase 23 | name 24 | Copy Pods Resources 25 | outputPaths 26 | 27 | runOnlyForDeploymentPostprocessing 28 | 0 29 | shellPath 30 | /bin/sh 31 | shellScript 32 | "${SRCROOT}/Pods/Pods-resources.sh" 33 | 34 | showEnvVarsInLog 35 | 0 36 | 37 | 222120D21932FFF700E0032A 38 | 39 | children 40 | 41 | 222120E41932FFF700E0032A 42 | 222120DD1932FFF700E0032A 43 | 222120DC1932FFF700E0032A 44 | 7A14835957A5428D8610ADCA 45 | 46 | isa 47 | PBXGroup 48 | sourceTree 49 | <group> 50 | 51 | 222120D31932FFF700E0032A 52 | 53 | attributes 54 | 55 | CLASSPREFIX 56 | AHK 57 | LastUpgradeCheck 58 | 0510 59 | ORGANIZATIONNAME 60 | Suffixlab 61 | 62 | buildConfigurationList 63 | 222120D61932FFF700E0032A 64 | compatibilityVersion 65 | Xcode 3.2 66 | developmentRegion 67 | English 68 | hasScannedForEncodings 69 | 0 70 | isa 71 | PBXProject 72 | knownRegions 73 | 74 | en 75 | 76 | mainGroup 77 | 222120D21932FFF700E0032A 78 | productRefGroup 79 | 222120DC1932FFF700E0032A 80 | projectDirPath 81 | 82 | projectReferences 83 | 84 | projectRoot 85 | 86 | targets 87 | 88 | 222120DA1932FFF700E0032A 89 | 90 | 91 | 222120D61932FFF700E0032A 92 | 93 | buildConfigurations 94 | 95 | 222121051932FFF700E0032A 96 | 222121061932FFF700E0032A 97 | 98 | defaultConfigurationIsVisible 99 | 0 100 | defaultConfigurationName 101 | Release 102 | isa 103 | XCConfigurationList 104 | 105 | 222120D71932FFF700E0032A 106 | 107 | buildActionMask 108 | 2147483647 109 | files 110 | 111 | 222120EB1932FFF700E0032A 112 | 222121101933007A00E0032A 113 | 222120EF1932FFF700E0032A 114 | 115 | isa 116 | PBXSourcesBuildPhase 117 | runOnlyForDeploymentPostprocessing 118 | 0 119 | 120 | 222120D81932FFF700E0032A 121 | 122 | buildActionMask 123 | 2147483647 124 | files 125 | 126 | 222120E11932FFF700E0032A 127 | 222120E31932FFF700E0032A 128 | 222120DF1932FFF700E0032A 129 | 9989205A06EF472B9431CED3 130 | 131 | isa 132 | PBXFrameworksBuildPhase 133 | runOnlyForDeploymentPostprocessing 134 | 0 135 | 136 | 222120D91932FFF700E0032A 137 | 138 | buildActionMask 139 | 2147483647 140 | files 141 | 142 | 222121111933007A00E0032A 143 | 222120E91932FFF700E0032A 144 | 222120F11932FFF700E0032A 145 | 146 | isa 147 | PBXResourcesBuildPhase 148 | runOnlyForDeploymentPostprocessing 149 | 0 150 | 151 | 222120DA1932FFF700E0032A 152 | 153 | buildConfigurationList 154 | 222121071932FFF700E0032A 155 | buildPhases 156 | 157 | D481C39DD57141FBB4A698A6 158 | 222120D71932FFF700E0032A 159 | 222120D81932FFF700E0032A 160 | 222120D91932FFF700E0032A 161 | 130781B44ACA453CA2FA6234 162 | 163 | buildRules 164 | 165 | dependencies 166 | 167 | isa 168 | PBXNativeTarget 169 | name 170 | AHKNavigationController 171 | productName 172 | AHKNavigationController 173 | productReference 174 | 222120DB1932FFF700E0032A 175 | productType 176 | com.apple.product-type.application 177 | 178 | 222120DB1932FFF700E0032A 179 | 180 | explicitFileType 181 | wrapper.application 182 | includeInIndex 183 | 0 184 | isa 185 | PBXFileReference 186 | path 187 | AHKNavigationController.app 188 | sourceTree 189 | BUILT_PRODUCTS_DIR 190 | 191 | 222120DC1932FFF700E0032A 192 | 193 | children 194 | 195 | 222120DB1932FFF700E0032A 196 | 197 | isa 198 | PBXGroup 199 | name 200 | Products 201 | sourceTree 202 | <group> 203 | 204 | 222120DD1932FFF700E0032A 205 | 206 | children 207 | 208 | 222120DE1932FFF700E0032A 209 | 222120E01932FFF700E0032A 210 | 222120E21932FFF700E0032A 211 | 222120F71932FFF700E0032A 212 | 9363C7858FBE4895BA12D32E 213 | 214 | isa 215 | PBXGroup 216 | name 217 | Frameworks 218 | sourceTree 219 | <group> 220 | 221 | 222120DE1932FFF700E0032A 222 | 223 | isa 224 | PBXFileReference 225 | lastKnownFileType 226 | wrapper.framework 227 | name 228 | Foundation.framework 229 | path 230 | System/Library/Frameworks/Foundation.framework 231 | sourceTree 232 | SDKROOT 233 | 234 | 222120DF1932FFF700E0032A 235 | 236 | fileRef 237 | 222120DE1932FFF700E0032A 238 | isa 239 | PBXBuildFile 240 | 241 | 222120E01932FFF700E0032A 242 | 243 | isa 244 | PBXFileReference 245 | lastKnownFileType 246 | wrapper.framework 247 | name 248 | CoreGraphics.framework 249 | path 250 | System/Library/Frameworks/CoreGraphics.framework 251 | sourceTree 252 | SDKROOT 253 | 254 | 222120E11932FFF700E0032A 255 | 256 | fileRef 257 | 222120E01932FFF700E0032A 258 | isa 259 | PBXBuildFile 260 | 261 | 222120E21932FFF700E0032A 262 | 263 | isa 264 | PBXFileReference 265 | lastKnownFileType 266 | wrapper.framework 267 | name 268 | UIKit.framework 269 | path 270 | System/Library/Frameworks/UIKit.framework 271 | sourceTree 272 | SDKROOT 273 | 274 | 222120E31932FFF700E0032A 275 | 276 | fileRef 277 | 222120E21932FFF700E0032A 278 | isa 279 | PBXBuildFile 280 | 281 | 222120E41932FFF700E0032A 282 | 283 | children 284 | 285 | 222120ED1932FFF700E0032A 286 | 222120EE1932FFF700E0032A 287 | 2221210D1933007A00E0032A 288 | 2221210E1933007A00E0032A 289 | 2221210F1933007A00E0032A 290 | 222120F01932FFF700E0032A 291 | 222120E51932FFF700E0032A 292 | 293 | isa 294 | PBXGroup 295 | path 296 | AHKNavigationController 297 | sourceTree 298 | <group> 299 | 300 | 222120E51932FFF700E0032A 301 | 302 | children 303 | 304 | 222120EA1932FFF700E0032A 305 | 222120EC1932FFF700E0032A 306 | 222120E61932FFF700E0032A 307 | 222120E71932FFF700E0032A 308 | 309 | isa 310 | PBXGroup 311 | name 312 | Supporting Files 313 | sourceTree 314 | <group> 315 | 316 | 222120E61932FFF700E0032A 317 | 318 | isa 319 | PBXFileReference 320 | lastKnownFileType 321 | text.plist.xml 322 | path 323 | AHKNavigationController-Info.plist 324 | sourceTree 325 | <group> 326 | 327 | 222120E71932FFF700E0032A 328 | 329 | children 330 | 331 | 222120E81932FFF700E0032A 332 | 333 | isa 334 | PBXVariantGroup 335 | name 336 | InfoPlist.strings 337 | sourceTree 338 | <group> 339 | 340 | 222120E81932FFF700E0032A 341 | 342 | isa 343 | PBXFileReference 344 | lastKnownFileType 345 | text.plist.strings 346 | name 347 | en 348 | path 349 | en.lproj/InfoPlist.strings 350 | sourceTree 351 | <group> 352 | 353 | 222120E91932FFF700E0032A 354 | 355 | fileRef 356 | 222120E71932FFF700E0032A 357 | isa 358 | PBXBuildFile 359 | 360 | 222120EA1932FFF700E0032A 361 | 362 | isa 363 | PBXFileReference 364 | lastKnownFileType 365 | sourcecode.c.objc 366 | path 367 | main.m 368 | sourceTree 369 | <group> 370 | 371 | 222120EB1932FFF700E0032A 372 | 373 | fileRef 374 | 222120EA1932FFF700E0032A 375 | isa 376 | PBXBuildFile 377 | 378 | 222120EC1932FFF700E0032A 379 | 380 | isa 381 | PBXFileReference 382 | lastKnownFileType 383 | sourcecode.c.h 384 | path 385 | AHKNavigationController-Prefix.pch 386 | sourceTree 387 | <group> 388 | 389 | 222120ED1932FFF700E0032A 390 | 391 | isa 392 | PBXFileReference 393 | lastKnownFileType 394 | sourcecode.c.h 395 | path 396 | AHKAppDelegate.h 397 | sourceTree 398 | <group> 399 | 400 | 222120EE1932FFF700E0032A 401 | 402 | isa 403 | PBXFileReference 404 | lastKnownFileType 405 | sourcecode.c.objc 406 | path 407 | AHKAppDelegate.m 408 | sourceTree 409 | <group> 410 | 411 | 222120EF1932FFF700E0032A 412 | 413 | fileRef 414 | 222120EE1932FFF700E0032A 415 | isa 416 | PBXBuildFile 417 | 418 | 222120F01932FFF700E0032A 419 | 420 | isa 421 | PBXFileReference 422 | lastKnownFileType 423 | folder.assetcatalog 424 | path 425 | Images.xcassets 426 | sourceTree 427 | <group> 428 | 429 | 222120F11932FFF700E0032A 430 | 431 | fileRef 432 | 222120F01932FFF700E0032A 433 | isa 434 | PBXBuildFile 435 | 436 | 222120F71932FFF700E0032A 437 | 438 | isa 439 | PBXFileReference 440 | lastKnownFileType 441 | wrapper.framework 442 | name 443 | XCTest.framework 444 | path 445 | Library/Frameworks/XCTest.framework 446 | sourceTree 447 | DEVELOPER_DIR 448 | 449 | 222121051932FFF700E0032A 450 | 451 | buildSettings 452 | 453 | ALWAYS_SEARCH_USER_PATHS 454 | NO 455 | CLANG_CXX_LANGUAGE_STANDARD 456 | gnu++0x 457 | CLANG_CXX_LIBRARY 458 | libc++ 459 | CLANG_ENABLE_MODULES 460 | YES 461 | CLANG_ENABLE_OBJC_ARC 462 | YES 463 | CLANG_WARN_BOOL_CONVERSION 464 | YES 465 | CLANG_WARN_CONSTANT_CONVERSION 466 | YES 467 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE 468 | YES_ERROR 469 | CLANG_WARN_EMPTY_BODY 470 | YES 471 | CLANG_WARN_ENUM_CONVERSION 472 | YES 473 | CLANG_WARN_INT_CONVERSION 474 | YES 475 | CLANG_WARN_OBJC_ROOT_CLASS 476 | YES_ERROR 477 | CLANG_WARN__DUPLICATE_METHOD_MATCH 478 | YES 479 | CODE_SIGN_IDENTITY[sdk=iphoneos*] 480 | iPhone Developer 481 | COPY_PHASE_STRIP 482 | NO 483 | GCC_C_LANGUAGE_STANDARD 484 | gnu99 485 | GCC_DYNAMIC_NO_PIC 486 | NO 487 | GCC_OPTIMIZATION_LEVEL 488 | 0 489 | GCC_PREPROCESSOR_DEFINITIONS 490 | 491 | DEBUG=1 492 | $(inherited) 493 | 494 | GCC_SYMBOLS_PRIVATE_EXTERN 495 | NO 496 | GCC_WARN_64_TO_32_BIT_CONVERSION 497 | YES 498 | GCC_WARN_ABOUT_RETURN_TYPE 499 | YES_ERROR 500 | GCC_WARN_UNDECLARED_SELECTOR 501 | YES 502 | GCC_WARN_UNINITIALIZED_AUTOS 503 | YES_AGGRESSIVE 504 | GCC_WARN_UNUSED_FUNCTION 505 | YES 506 | GCC_WARN_UNUSED_VARIABLE 507 | YES 508 | IPHONEOS_DEPLOYMENT_TARGET 509 | 7.1 510 | ONLY_ACTIVE_ARCH 511 | YES 512 | SDKROOT 513 | iphoneos 514 | TARGETED_DEVICE_FAMILY 515 | 1,2 516 | 517 | isa 518 | XCBuildConfiguration 519 | name 520 | Debug 521 | 522 | 222121061932FFF700E0032A 523 | 524 | buildSettings 525 | 526 | ALWAYS_SEARCH_USER_PATHS 527 | NO 528 | CLANG_CXX_LANGUAGE_STANDARD 529 | gnu++0x 530 | CLANG_CXX_LIBRARY 531 | libc++ 532 | CLANG_ENABLE_MODULES 533 | YES 534 | CLANG_ENABLE_OBJC_ARC 535 | YES 536 | CLANG_WARN_BOOL_CONVERSION 537 | YES 538 | CLANG_WARN_CONSTANT_CONVERSION 539 | YES 540 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE 541 | YES_ERROR 542 | CLANG_WARN_EMPTY_BODY 543 | YES 544 | CLANG_WARN_ENUM_CONVERSION 545 | YES 546 | CLANG_WARN_INT_CONVERSION 547 | YES 548 | CLANG_WARN_OBJC_ROOT_CLASS 549 | YES_ERROR 550 | CLANG_WARN__DUPLICATE_METHOD_MATCH 551 | YES 552 | CODE_SIGN_IDENTITY[sdk=iphoneos*] 553 | iPhone Developer 554 | COPY_PHASE_STRIP 555 | YES 556 | ENABLE_NS_ASSERTIONS 557 | NO 558 | GCC_C_LANGUAGE_STANDARD 559 | gnu99 560 | GCC_WARN_64_TO_32_BIT_CONVERSION 561 | YES 562 | GCC_WARN_ABOUT_RETURN_TYPE 563 | YES_ERROR 564 | GCC_WARN_UNDECLARED_SELECTOR 565 | YES 566 | GCC_WARN_UNINITIALIZED_AUTOS 567 | YES_AGGRESSIVE 568 | GCC_WARN_UNUSED_FUNCTION 569 | YES 570 | GCC_WARN_UNUSED_VARIABLE 571 | YES 572 | IPHONEOS_DEPLOYMENT_TARGET 573 | 7.1 574 | SDKROOT 575 | iphoneos 576 | TARGETED_DEVICE_FAMILY 577 | 1,2 578 | VALIDATE_PRODUCT 579 | YES 580 | 581 | isa 582 | XCBuildConfiguration 583 | name 584 | Release 585 | 586 | 222121071932FFF700E0032A 587 | 588 | buildConfigurations 589 | 590 | 222121081932FFF700E0032A 591 | 222121091932FFF700E0032A 592 | 593 | defaultConfigurationIsVisible 594 | 0 595 | defaultConfigurationName 596 | Release 597 | isa 598 | XCConfigurationList 599 | 600 | 222121081932FFF700E0032A 601 | 602 | baseConfigurationReference 603 | 7A14835957A5428D8610ADCA 604 | buildSettings 605 | 606 | ASSETCATALOG_COMPILER_APPICON_NAME 607 | AppIcon 608 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME 609 | LaunchImage 610 | GCC_PRECOMPILE_PREFIX_HEADER 611 | YES 612 | GCC_PREFIX_HEADER 613 | AHKNavigationController/AHKNavigationController-Prefix.pch 614 | INFOPLIST_FILE 615 | AHKNavigationController/AHKNavigationController-Info.plist 616 | IPHONEOS_DEPLOYMENT_TARGET 617 | 7.0 618 | PRODUCT_NAME 619 | $(TARGET_NAME) 620 | WRAPPER_EXTENSION 621 | app 622 | 623 | isa 624 | XCBuildConfiguration 625 | name 626 | Debug 627 | 628 | 222121091932FFF700E0032A 629 | 630 | baseConfigurationReference 631 | 7A14835957A5428D8610ADCA 632 | buildSettings 633 | 634 | ASSETCATALOG_COMPILER_APPICON_NAME 635 | AppIcon 636 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME 637 | LaunchImage 638 | GCC_PRECOMPILE_PREFIX_HEADER 639 | YES 640 | GCC_PREFIX_HEADER 641 | AHKNavigationController/AHKNavigationController-Prefix.pch 642 | INFOPLIST_FILE 643 | AHKNavigationController/AHKNavigationController-Info.plist 644 | IPHONEOS_DEPLOYMENT_TARGET 645 | 7.0 646 | PRODUCT_NAME 647 | $(TARGET_NAME) 648 | WRAPPER_EXTENSION 649 | app 650 | 651 | isa 652 | XCBuildConfiguration 653 | name 654 | Release 655 | 656 | 2221210D1933007A00E0032A 657 | 658 | fileEncoding 659 | 4 660 | isa 661 | PBXFileReference 662 | lastKnownFileType 663 | sourcecode.c.h 664 | path 665 | AHKTestViewController.h 666 | sourceTree 667 | <group> 668 | 669 | 2221210E1933007A00E0032A 670 | 671 | fileEncoding 672 | 4 673 | isa 674 | PBXFileReference 675 | lastKnownFileType 676 | sourcecode.c.objc 677 | path 678 | AHKTestViewController.m 679 | sourceTree 680 | <group> 681 | 682 | 2221210F1933007A00E0032A 683 | 684 | fileEncoding 685 | 4 686 | isa 687 | PBXFileReference 688 | lastKnownFileType 689 | file.xib 690 | path 691 | AHKTestViewController.xib 692 | sourceTree 693 | <group> 694 | 695 | 222121101933007A00E0032A 696 | 697 | fileRef 698 | 2221210E1933007A00E0032A 699 | isa 700 | PBXBuildFile 701 | 702 | 222121111933007A00E0032A 703 | 704 | fileRef 705 | 2221210F1933007A00E0032A 706 | isa 707 | PBXBuildFile 708 | 709 | 7A14835957A5428D8610ADCA 710 | 711 | includeInIndex 712 | 1 713 | isa 714 | PBXFileReference 715 | lastKnownFileType 716 | text.xcconfig 717 | name 718 | Pods.xcconfig 719 | path 720 | Pods/Pods.xcconfig 721 | sourceTree 722 | <group> 723 | 724 | 9363C7858FBE4895BA12D32E 725 | 726 | explicitFileType 727 | archive.ar 728 | includeInIndex 729 | 0 730 | isa 731 | PBXFileReference 732 | path 733 | libPods.a 734 | sourceTree 735 | BUILT_PRODUCTS_DIR 736 | 737 | 9989205A06EF472B9431CED3 738 | 739 | fileRef 740 | 9363C7858FBE4895BA12D32E 741 | isa 742 | PBXBuildFile 743 | 744 | D481C39DD57141FBB4A698A6 745 | 746 | buildActionMask 747 | 2147483647 748 | files 749 | 750 | inputPaths 751 | 752 | isa 753 | PBXShellScriptBuildPhase 754 | name 755 | Check Pods Manifest.lock 756 | outputPaths 757 | 758 | runOnlyForDeploymentPostprocessing 759 | 0 760 | shellPath 761 | /bin/sh 762 | shellScript 763 | diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null 764 | if [[ $? != 0 ]] ; then 765 | cat << EOM 766 | error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. 767 | EOM 768 | exit 1 769 | fi 770 | 771 | showEnvVarsInLog 772 | 0 773 | 774 | 775 | rootObject 776 | 222120D31932FFF700E0032A 777 | 778 | 779 | -------------------------------------------------------------------------------- /Example/AHKNavigationController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKAppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AHKAppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AHKAppDelegate.h" 2 | #import "AHKNavigationController.h" 3 | #import "AHKTestViewController.h" 4 | 5 | @implementation AHKAppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | AHKTestViewController *controller = [[AHKTestViewController alloc] initWithNibName:nil bundle:nil]; 10 | AHKNavigationController *nav = [[AHKNavigationController alloc] initWithRootViewController:controller]; 11 | nav.navigationBarHidden = YES; 12 | 13 | CGRect frame = [UIScreen mainScreen].bounds; 14 | UIWindow *window = [[UIWindow alloc] initWithFrame:frame]; 15 | window.rootViewController = nav; 16 | window.backgroundColor = [UIColor whiteColor]; 17 | [window makeKeyAndVisible]; 18 | self.window = window; 19 | 20 | return YES; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKNavigationController-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | net.chakrit.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 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 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKNavigationController-Prefix.pch: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #ifndef __IPHONE_3_0 4 | #warning "This project uses features only available in iOS SDK 3.0 and later." 5 | #endif 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import 10 | #endif 11 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKTestViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AHKTestViewController : UIViewController 4 | @end 5 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKTestViewController.m: -------------------------------------------------------------------------------- 1 | #import "AHKTestViewController.h" 2 | 3 | @interface AHKTestViewController () 4 | @property (weak, nonatomic) IBOutlet UIButton *backButton; 5 | @property (nonatomic, assign) IBOutlet UILabel *titleLabel; 6 | @end 7 | 8 | @implementation AHKTestViewController 9 | 10 | #pragma mark - UIViewController 11 | 12 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 13 | { 14 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 15 | NSNumber *num = @((int)self); 16 | self.title = [num stringValue]; 17 | } 18 | return self; 19 | } 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | 25 | self.titleLabel.text = self.title; 26 | 27 | if ([self.navigationController.viewControllers count] < 2) { 28 | self.backButton.hidden = YES; 29 | } 30 | } 31 | 32 | - (UIRectEdge)edgesForExtendedLayout 33 | { 34 | return UIRectEdgeNone; 35 | } 36 | 37 | #pragma mark - Actions 38 | 39 | - (IBAction)popButtonTapped:(id)sender 40 | { 41 | [self.navigationController popViewControllerAnimated:YES]; 42 | } 43 | 44 | - (IBAction)pushButtonTapped:(id)sender 45 | { 46 | AHKTestViewController *next = [[AHKTestViewController alloc] initWithNibName:nil bundle:nil]; 47 | [self.navigationController pushViewController:next animated:YES]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/AHKTestViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 30 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Example/AHKNavigationController/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Example/AHKNavigationController/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/AHKNavigationController/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "AHKAppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) 5 | { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AHKAppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" 2 | 3 | pod "AHKNavigationController", :path => "../" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2014 AHKNavigationController authors and contributors. 3 | 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, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 21 | OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AHKNavigationController 2 | [![License: MIT](https://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://github.com/fastred/AHKNavigationController/blob/master/LICENSE) 3 | [![CocoaPods](https://img.shields.io/cocoapods/v/AHKNavigationController.svg?style=flat)](https://github.com/fastred/AHKNavigationController) 4 | 5 | 6 | A `UINavigationController` subclass that re-enables the interactive pop gesture (`UIScreenEdgePanGestureRecognizer` instance) when the navigation bar is hidden or a custom back button is used. 7 | 8 | The solution is explained in detail in a blog post: 9 | [Interactive Pop Gesture with Custom Back Button or Hidden Navigation Bar][0] 10 | 11 | ## Demo 12 | 13 | To run the example project: clone the repo, and run `pod install` from the Example directory first. Alternatively, run `pod try AHKNavigationController` from the command line. 14 | 15 | ## Requirements 16 | 17 | * iOS 7 18 | * ARC enabled 19 | 20 | ## Installation 21 | 22 | AHKNavigationController is available through [CocoaPods](http://cocoapods.org). To install 23 | it, simply add the following line to your Podfile: 24 | 25 | pod "AHKNavigationController" 26 | 27 | and set your navigation controller to be an instance of `AHKNavigationController` or its subclass. 28 | 29 | If you don't use CocoaPods, you can simply copy the files from `Classes/` directory to your project. 30 | 31 | ## Author 32 | 33 | Arkadiusz Holko: 34 | 35 | * [Blog](http://holko.pl/) 36 | * [@arekholko on Twitter](https://twitter.com/arekholko) 37 | 38 | ## Credits 39 | 40 | The example project was created by [@chakrit](https://github.com/chakrit). 41 | 42 | 43 | [0]: http://holko.pl/ios/2014/04/06/interactive-pop-gesture/ 44 | --------------------------------------------------------------------------------