├── .gitattributes ├── .gitignore ├── ANAdvancedNavigationController ├── ANAdvancedNavigationController.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── ANAdvancedNavigationController │ ├── ANAdvancedNavigationController-Prefix.pch │ ├── ANAdvancedNavigationController.h │ ├── ANAdvancedNavigationController.m │ ├── ANRectangleView.h │ ├── ANRectangleView.m │ ├── ANRemoveRectangleIndicatorView.h │ ├── ANRemoveRectangleIndicatorView.m │ └── Private │ ├── ANAdvancedNavigationController+private.h │ ├── LeftViewController │ ├── ANAdvancedNavigationController+LeftViewController.h │ └── ANAdvancedNavigationController+LeftViewController.m │ └── RightViewControllers │ ├── ANAdvancedNavigationController+RightViewControllers+Anchors.h │ ├── ANAdvancedNavigationController+RightViewControllers+Anchors.m │ ├── ANAdvancedNavigationController+RightViewControllers.h │ └── ANAdvancedNavigationController+RightViewControllers.m ├── LICENSE.md ├── README.md ├── SampleApplication ├── ANAdvancedNavigationController.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── ANAdvancedNavigationController │ ├── ANAdvancedNavigationController-Prefix.pch │ ├── ANAdvancedNavigationController.h │ ├── ANAdvancedNavigationController.m │ ├── ANRectangleView.h │ ├── ANRectangleView.m │ ├── ANRemoveRectangleIndicatorView.h │ ├── ANRemoveRectangleIndicatorView.m │ └── Private │ │ ├── ANAdvancedNavigationController+private.h │ │ ├── LeftViewController │ │ ├── ANAdvancedNavigationController+LeftViewController.h │ │ └── ANAdvancedNavigationController+LeftViewController.m │ │ └── RightViewControllers │ │ ├── ANAdvancedNavigationController+RightViewControllers+Anchors.h │ │ ├── ANAdvancedNavigationController+RightViewControllers+Anchors.m │ │ ├── ANAdvancedNavigationController+RightViewControllers.h │ │ └── ANAdvancedNavigationController+RightViewControllers.m ├── SampleApplication.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── SampleApplication │ ├── SampleApplication-Info.plist │ ├── SampleApplication-Prefix.pch │ ├── SampleApplicationAppDelegate.h │ ├── SampleApplicationAppDelegate.m │ ├── ViewControllers │ ├── LeftViewController.h │ ├── LeftViewController.m │ ├── RightViewController.h │ └── RightViewController.m │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m └── Screenshots ├── 1.jpg └── 2.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -crlf -diff -merge 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # xcode noise 2 | *.mode1v3 3 | *.pbxuser 4 | *.perspective 5 | *.perspectivev3 6 | *.pyc 7 | *~.nib/ 8 | build/ 9 | xcuserdata/ 10 | xcuserdata/* 11 | *.xcuserdatad/ 12 | 13 | # Textmate - if you build your xcode projects with it 14 | *.tm_build_errors 15 | 16 | # old skool 17 | .svn 18 | 19 | # osx noise 20 | .DS_Store 21 | profile 22 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A7B6544513EA9143009E4414 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7B6544413EA9143009E4414 /* QuartzCore.framework */; }; 11 | A7C3773613EA8EF800B9943A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7C3773513EA8EF800B9943A /* Foundation.framework */; }; 12 | A7C3775313EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774213EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch */; }; 13 | A7C3775413EA8F2500B9943A /* ANAdvancedNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774313EA8F2500B9943A /* ANAdvancedNavigationController.h */; }; 14 | A7C3775513EA8F2500B9943A /* ANAdvancedNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774413EA8F2500B9943A /* ANAdvancedNavigationController.m */; }; 15 | A7C3775613EA8F2500B9943A /* ANRectangleView.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774513EA8F2500B9943A /* ANRectangleView.h */; }; 16 | A7C3775713EA8F2500B9943A /* ANRectangleView.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774613EA8F2500B9943A /* ANRectangleView.m */; }; 17 | A7C3775813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774713EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h */; }; 18 | A7C3775913EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m */; }; 19 | A7C3775A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h */; }; 20 | A7C3775B13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h */; }; 21 | A7C3775C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774D13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m */; }; 22 | A7C3775D13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h */; }; 23 | A7C3775E13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3775013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m */; }; 24 | A7C3775F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3775113EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h */; }; 25 | A7C3776013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3775213EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | A7B6544413EA9143009E4414 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 30 | A7C3773213EA8EF800B9943A /* libANAdvancedNavigationController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libANAdvancedNavigationController.a; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | A7C3773513EA8EF800B9943A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 32 | A7C3773913EA8EF800B9943A /* ANAdvancedNavigationController-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController-Prefix.pch"; sourceTree = ""; }; 33 | A7C3774213EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController-Prefix.pch"; sourceTree = ""; }; 34 | A7C3774313EA8F2500B9943A /* ANAdvancedNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANAdvancedNavigationController.h; sourceTree = ""; }; 35 | A7C3774413EA8F2500B9943A /* ANAdvancedNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANAdvancedNavigationController.m; sourceTree = ""; }; 36 | A7C3774513EA8F2500B9943A /* ANRectangleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANRectangleView.h; sourceTree = ""; }; 37 | A7C3774613EA8F2500B9943A /* ANRectangleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANRectangleView.m; sourceTree = ""; }; 38 | A7C3774713EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANRemoveRectangleIndicatorView.h; sourceTree = ""; }; 39 | A7C3774813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANRemoveRectangleIndicatorView.m; sourceTree = ""; }; 40 | A7C3774A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+private.h"; sourceTree = ""; }; 41 | A7C3774C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+LeftViewController.h"; sourceTree = ""; }; 42 | A7C3774D13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ANAdvancedNavigationController+LeftViewController.m"; sourceTree = ""; }; 43 | A7C3774F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+RightViewControllers+Anchors.h"; sourceTree = ""; }; 44 | A7C3775013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ANAdvancedNavigationController+RightViewControllers+Anchors.m"; sourceTree = ""; }; 45 | A7C3775113EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+RightViewControllers.h"; sourceTree = ""; }; 46 | A7C3775213EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ANAdvancedNavigationController+RightViewControllers.m"; sourceTree = ""; }; 47 | /* End PBXFileReference section */ 48 | 49 | /* Begin PBXFrameworksBuildPhase section */ 50 | A7C3772F13EA8EF800B9943A /* Frameworks */ = { 51 | isa = PBXFrameworksBuildPhase; 52 | buildActionMask = 2147483647; 53 | files = ( 54 | A7B6544513EA9143009E4414 /* QuartzCore.framework in Frameworks */, 55 | A7C3773613EA8EF800B9943A /* Foundation.framework in Frameworks */, 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXFrameworksBuildPhase section */ 60 | 61 | /* Begin PBXGroup section */ 62 | A7C3772713EA8EF800B9943A = { 63 | isa = PBXGroup; 64 | children = ( 65 | A7C3773713EA8EF800B9943A /* ANAdvancedNavigationController */, 66 | A7C3773413EA8EF800B9943A /* Frameworks */, 67 | A7C3773313EA8EF800B9943A /* Products */, 68 | ); 69 | sourceTree = ""; 70 | }; 71 | A7C3773313EA8EF800B9943A /* Products */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | A7C3773213EA8EF800B9943A /* libANAdvancedNavigationController.a */, 75 | ); 76 | name = Products; 77 | sourceTree = ""; 78 | }; 79 | A7C3773413EA8EF800B9943A /* Frameworks */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | A7B6544413EA9143009E4414 /* QuartzCore.framework */, 83 | A7C3773513EA8EF800B9943A /* Foundation.framework */, 84 | ); 85 | name = Frameworks; 86 | sourceTree = ""; 87 | }; 88 | A7C3773713EA8EF800B9943A /* ANAdvancedNavigationController */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | A7C3774213EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch */, 92 | A7C3774313EA8F2500B9943A /* ANAdvancedNavigationController.h */, 93 | A7C3774413EA8F2500B9943A /* ANAdvancedNavigationController.m */, 94 | A7C3774513EA8F2500B9943A /* ANRectangleView.h */, 95 | A7C3774613EA8F2500B9943A /* ANRectangleView.m */, 96 | A7C3774713EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h */, 97 | A7C3774813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m */, 98 | A7C3774913EA8F2500B9943A /* Private */, 99 | A7C3773813EA8EF800B9943A /* Supporting Files */, 100 | ); 101 | path = ANAdvancedNavigationController; 102 | sourceTree = ""; 103 | }; 104 | A7C3773813EA8EF800B9943A /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | A7C3773913EA8EF800B9943A /* ANAdvancedNavigationController-Prefix.pch */, 108 | ); 109 | name = "Supporting Files"; 110 | sourceTree = ""; 111 | }; 112 | A7C3774913EA8F2500B9943A /* Private */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | A7C3774A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h */, 116 | A7C3774B13EA8F2500B9943A /* LeftViewController */, 117 | A7C3774E13EA8F2500B9943A /* RightViewControllers */, 118 | ); 119 | path = Private; 120 | sourceTree = ""; 121 | }; 122 | A7C3774B13EA8F2500B9943A /* LeftViewController */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | A7C3774C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h */, 126 | A7C3774D13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m */, 127 | ); 128 | path = LeftViewController; 129 | sourceTree = ""; 130 | }; 131 | A7C3774E13EA8F2500B9943A /* RightViewControllers */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | A7C3774F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h */, 135 | A7C3775013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m */, 136 | A7C3775113EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h */, 137 | A7C3775213EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m */, 138 | ); 139 | path = RightViewControllers; 140 | sourceTree = ""; 141 | }; 142 | /* End PBXGroup section */ 143 | 144 | /* Begin PBXHeadersBuildPhase section */ 145 | A7C3773013EA8EF800B9943A /* Headers */ = { 146 | isa = PBXHeadersBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | A7C3775313EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch in Headers */, 150 | A7C3775413EA8F2500B9943A /* ANAdvancedNavigationController.h in Headers */, 151 | A7C3775613EA8F2500B9943A /* ANRectangleView.h in Headers */, 152 | A7C3775813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h in Headers */, 153 | A7C3775A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h in Headers */, 154 | A7C3775B13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h in Headers */, 155 | A7C3775D13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h in Headers */, 156 | A7C3775F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h in Headers */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXHeadersBuildPhase section */ 161 | 162 | /* Begin PBXNativeTarget section */ 163 | A7C3773113EA8EF800B9943A /* ANAdvancedNavigationController */ = { 164 | isa = PBXNativeTarget; 165 | buildConfigurationList = A7C3773F13EA8EF800B9943A /* Build configuration list for PBXNativeTarget "ANAdvancedNavigationController" */; 166 | buildPhases = ( 167 | A7C3772E13EA8EF800B9943A /* Sources */, 168 | A7C3772F13EA8EF800B9943A /* Frameworks */, 169 | A7C3773013EA8EF800B9943A /* Headers */, 170 | ); 171 | buildRules = ( 172 | ); 173 | dependencies = ( 174 | ); 175 | name = ANAdvancedNavigationController; 176 | productName = ANAdvancedNavigationController; 177 | productReference = A7C3773213EA8EF800B9943A /* libANAdvancedNavigationController.a */; 178 | productType = "com.apple.product-type.library.static"; 179 | }; 180 | /* End PBXNativeTarget section */ 181 | 182 | /* Begin PBXProject section */ 183 | A7C3772913EA8EF800B9943A /* Project object */ = { 184 | isa = PBXProject; 185 | attributes = { 186 | LastUpgradeCheck = 0420; 187 | ORGANIZATIONNAME = Home; 188 | }; 189 | buildConfigurationList = A7C3772C13EA8EF800B9943A /* Build configuration list for PBXProject "ANAdvancedNavigationController" */; 190 | compatibilityVersion = "Xcode 3.2"; 191 | developmentRegion = English; 192 | hasScannedForEncodings = 0; 193 | knownRegions = ( 194 | en, 195 | ); 196 | mainGroup = A7C3772713EA8EF800B9943A; 197 | productRefGroup = A7C3773313EA8EF800B9943A /* Products */; 198 | projectDirPath = ""; 199 | projectRoot = ""; 200 | targets = ( 201 | A7C3773113EA8EF800B9943A /* ANAdvancedNavigationController */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXSourcesBuildPhase section */ 207 | A7C3772E13EA8EF800B9943A /* Sources */ = { 208 | isa = PBXSourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | A7C3775513EA8F2500B9943A /* ANAdvancedNavigationController.m in Sources */, 212 | A7C3775713EA8F2500B9943A /* ANRectangleView.m in Sources */, 213 | A7C3775913EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m in Sources */, 214 | A7C3775C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m in Sources */, 215 | A7C3775E13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m in Sources */, 216 | A7C3776013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m in Sources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXSourcesBuildPhase section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | A7C3773D13EA8EF800B9943A /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 228 | CLANG_ENABLE_OBJC_ARC = YES; 229 | COPY_PHASE_STRIP = NO; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_DYNAMIC_NO_PIC = NO; 232 | GCC_OPTIMIZATION_LEVEL = 0; 233 | GCC_PREPROCESSOR_DEFINITIONS = ( 234 | "DEBUG=1", 235 | "$(inherited)", 236 | ); 237 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 238 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 239 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 240 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 241 | GCC_WARN_UNUSED_VARIABLE = YES; 242 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 243 | SDKROOT = iphoneos; 244 | }; 245 | name = Debug; 246 | }; 247 | A7C3773E13EA8EF800B9943A /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | ALWAYS_SEARCH_USER_PATHS = NO; 251 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 252 | CLANG_ENABLE_OBJC_ARC = YES; 253 | COPY_PHASE_STRIP = YES; 254 | GCC_C_LANGUAGE_STANDARD = gnu99; 255 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 256 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 257 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 260 | SDKROOT = iphoneos; 261 | VALIDATE_PRODUCT = YES; 262 | }; 263 | name = Release; 264 | }; 265 | A7C3774013EA8EF800B9943A /* Debug */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | DSTROOT = /tmp/ANAdvancedNavigationController.dst; 269 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 270 | GCC_PREFIX_HEADER = "ANAdvancedNavigationController/ANAdvancedNavigationController-Prefix.pch"; 271 | OTHER_LDFLAGS = "-ObjC"; 272 | PRODUCT_NAME = "$(TARGET_NAME)"; 273 | SKIP_INSTALL = YES; 274 | }; 275 | name = Debug; 276 | }; 277 | A7C3774113EA8EF800B9943A /* Release */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | DSTROOT = /tmp/ANAdvancedNavigationController.dst; 281 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 282 | GCC_PREFIX_HEADER = "ANAdvancedNavigationController/ANAdvancedNavigationController-Prefix.pch"; 283 | OTHER_LDFLAGS = "-ObjC"; 284 | PRODUCT_NAME = "$(TARGET_NAME)"; 285 | SKIP_INSTALL = YES; 286 | }; 287 | name = Release; 288 | }; 289 | /* End XCBuildConfiguration section */ 290 | 291 | /* Begin XCConfigurationList section */ 292 | A7C3772C13EA8EF800B9943A /* Build configuration list for PBXProject "ANAdvancedNavigationController" */ = { 293 | isa = XCConfigurationList; 294 | buildConfigurations = ( 295 | A7C3773D13EA8EF800B9943A /* Debug */, 296 | A7C3773E13EA8EF800B9943A /* Release */, 297 | ); 298 | defaultConfigurationIsVisible = 0; 299 | defaultConfigurationName = Release; 300 | }; 301 | A7C3773F13EA8EF800B9943A /* Build configuration list for PBXNativeTarget "ANAdvancedNavigationController" */ = { 302 | isa = XCConfigurationList; 303 | buildConfigurations = ( 304 | A7C3774013EA8EF800B9943A /* Debug */, 305 | A7C3774113EA8EF800B9943A /* Release */, 306 | ); 307 | defaultConfigurationIsVisible = 0; 308 | defaultConfigurationName = Release; 309 | }; 310 | /* End XCConfigurationList section */ 311 | }; 312 | rootObject = A7C3772913EA8EF800B9943A /* Project object */; 313 | } 314 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANAdvancedNavigationController-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ANAdvancedNavigationController' target in the 'ANAdvancedNavigationController' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANAdvancedNavigationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern const CGFloat ANAdvancedNavigationControllerDefaultLeftViewControllerWidth; 12 | extern const CGFloat ANAdvancedNavigationControllerDefaultViewControllerWidth; 13 | extern const CGFloat ANAdvancedNavigationControllerDefaultLeftPanningOffset; 14 | 15 | @class ANAdvancedNavigationController; 16 | 17 | 18 | 19 | @protocol ANAdvancedNavigationControllerDelegate 20 | 21 | @optional 22 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController willPushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 23 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController didPushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 24 | 25 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController willPopToViewController:(UIViewController *)viewController animated:(BOOL)animated; 26 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController didPopToViewController:(UIViewController *)viewController animated:(BOOL)animated; 27 | 28 | @end 29 | 30 | 31 | 32 | 33 | 34 | @interface ANAdvancedNavigationController : UIViewController 35 | 36 | @property (nonatomic, retain) UIView *backgroundView; 37 | @property (nonatomic, retain) UIViewController *leftViewController; 38 | @property (nonatomic, readonly, copy) NSArray *rightViewControllers; 39 | 40 | @property (nonatomic, weak) id delegate; 41 | 42 | - (id)initWithLeftViewController:(UIViewController *)leftViewController; 43 | - (id)initWithLeftViewController:(UIViewController *)leftViewController rightViewControllers:(NSArray *)rightViewControllers; 44 | 45 | - (void)popViewController:(UIViewController *)viewController animated:(BOOL)animated; 46 | - (void)popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated; 47 | 48 | - (void)pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 49 | 50 | // will set/return the viewController, that is on anchor point right 51 | @property (nonatomic, assign) NSUInteger indexOfFrontViewController; 52 | 53 | @end 54 | 55 | 56 | 57 | 58 | @interface UIViewController (ANAdvancedNavigationController) 59 | @property (nonatomic, readonly) ANAdvancedNavigationController *advancedNavigationController; 60 | @end 61 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANAdvancedNavigationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | #import "ANAdvancedNavigationController+LeftViewController.h" 12 | #import "ANAdvancedNavigationController+RightViewControllers.h" 13 | #import 14 | 15 | const CGFloat ANAdvancedNavigationControllerDefaultLeftViewControllerWidth = 291.0f; 16 | const CGFloat ANAdvancedNavigationControllerDefaultViewControllerWidth = 475.0f; 17 | const CGFloat ANAdvancedNavigationControllerDefaultLeftPanningOffset = 75.0f; 18 | 19 | const CGFloat ANAdvancedNavigationControllerDefaultAnimationDuration = 0.35f; 20 | const CGFloat ANAdvancedNavigationControllerDefaultDraggingDistance = 473.0f; 21 | 22 | @implementation ANAdvancedNavigationController 23 | 24 | @synthesize backgroundView=_backgroundView; 25 | @synthesize leftViewController=_leftViewController, viewControllers=_viewControllers, removeRectangleIndicatorView=_removeRectangleIndicatorView; 26 | @synthesize delegate=_delegate; 27 | @synthesize draggingStartDate=_draggingStartDate; 28 | 29 | #pragma mark - setters and getters 30 | 31 | - (void)setLeftViewController:(UIViewController *)leftViewController { 32 | if (_leftViewController != leftViewController) { 33 | [self _setLeftViewController:leftViewController]; 34 | } 35 | } 36 | 37 | - (void)setBackgroundView:(UIView *)backgroundView { 38 | if (backgroundView != _backgroundView) { 39 | [_backgroundView removeFromSuperview]; 40 | _backgroundView = backgroundView; 41 | [self updateBackgroundView]; 42 | } 43 | } 44 | 45 | - (NSArray *)rightViewControllers { 46 | return [_viewControllers copy]; 47 | } 48 | 49 | - (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { 50 | return NO; 51 | } 52 | 53 | - (NSUInteger)indexOfFrontViewController { 54 | return _indexOfFrontViewController; 55 | } 56 | 57 | - (void)setIndexOfFrontViewController:(NSUInteger)indexOfFrontViewController { 58 | [self _setIndexOfFrontViewController:indexOfFrontViewController]; 59 | } 60 | 61 | #pragma mark - initialization 62 | 63 | - (id)init { 64 | if ((self = [super init])) { 65 | if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) { 66 | [NSException raise:NSInternalInconsistencyException format:@"ANAdvancedNavigationController is only supposed to work on iPad"]; 67 | } 68 | self.viewControllers = [NSMutableArray array]; 69 | } 70 | return self; 71 | } 72 | 73 | - (id)initWithLeftViewController:(UIViewController *)leftViewController { 74 | if ((self = [self init])) { 75 | self.leftViewController = leftViewController; 76 | } 77 | return self; 78 | } 79 | 80 | - (id)initWithLeftViewController:(UIViewController *)leftViewController rightViewControllers:(NSArray *)rightViewControllers { 81 | if (self = [self initWithLeftViewController:leftViewController]) { 82 | [rightViewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 83 | [self _insertRightViewControllerInDataModel:obj]; 84 | }]; 85 | } 86 | return self; 87 | } 88 | 89 | #pragma mark - Pushing and Poping 90 | 91 | - (void)popViewController:(UIViewController *)viewController animated:(BOOL)animated { 92 | if (![self.viewControllers containsObject:viewController]) { 93 | NSLog(@"viewController (%@) is not part of the viewController Hierarchy", viewController); 94 | return; 95 | } 96 | 97 | NSInteger index = [self.viewControllers indexOfObject:viewController]-1; 98 | 99 | if (index >= 0) { 100 | viewController = [self.viewControllers objectAtIndex:index]; 101 | [self _popViewControllersToViewController:viewController animated:animated]; 102 | } 103 | } 104 | 105 | - (void)popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated { 106 | [self _popViewControllersToViewController:viewController animated:animated]; 107 | } 108 | 109 | - (void)pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated { 110 | [self _pushViewController:viewController afterViewController:afterViewController animated:animated]; 111 | } 112 | 113 | #pragma mark - View lifecycle 114 | 115 | - (void)loadView { 116 | [super loadView]; 117 | 118 | CGFloat removeHeight = 75.0f; 119 | self.removeRectangleIndicatorView = [[ANRemoveRectangleIndicatorView alloc] initWithFrame:CGRectMake(ANAdvancedNavigationControllerDefaultLeftViewControllerWidth + 5.0f, CGRectGetHeight(self.view.bounds)/2.0f-removeHeight, 175.0f, removeHeight*2.0f)]; 120 | self.removeRectangleIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 121 | [self.view insertSubview:self.removeRectangleIndicatorView atIndex:0]; 122 | } 123 | 124 | - (void)viewDidLoad { 125 | [super viewDidLoad]; 126 | 127 | self.view.backgroundColor = [UIColor darkGrayColor]; 128 | [self updateBackgroundView]; 129 | [self _insertLeftViewControllerView]; 130 | [self _prepareViewForPanning]; 131 | [self _insertRightViewControllerViews]; 132 | } 133 | 134 | - (void)viewDidUnload { 135 | [super viewDidUnload]; 136 | _removeRectangleIndicatorView = nil; 137 | _draggingStartDate = nil; 138 | } 139 | 140 | - (void)viewWillDisappear:(BOOL)animated 141 | { 142 | [super viewWillDisappear:animated]; 143 | 144 | for (UIViewController *viewController in self.childViewControllers) { 145 | [viewController viewWillDisappear:animated]; 146 | } 147 | } 148 | 149 | - (void)viewDidDisappear:(BOOL)animated 150 | { 151 | [super viewDidDisappear:animated]; 152 | 153 | for (UIViewController *viewController in self.childViewControllers) { 154 | [viewController viewDidDisappear:animated]; 155 | } 156 | } 157 | 158 | - (void)viewWillAppear:(BOOL)animated 159 | { 160 | [super viewWillAppear:animated]; 161 | 162 | static BOOL isFirstViewWillAppear = YES; 163 | 164 | // we dont need to inform childViewControllers in our first viewWillAppear because this is handled in viewDidLoad. 165 | if (!isFirstViewWillAppear) { 166 | for (UIViewController *viewController in self.childViewControllers) { 167 | [viewController viewWillAppear:animated]; 168 | } 169 | } 170 | 171 | isFirstViewWillAppear = NO; 172 | } 173 | 174 | - (void)viewDidAppear:(BOOL)animated 175 | { 176 | [super viewDidAppear:animated]; 177 | 178 | static BOOL isFirstViewDidAppear = YES; 179 | 180 | // we dont need to inform childViewControllers in our first viewDidAppear because this is handled in viewDidLoad. 181 | if (!isFirstViewDidAppear) { 182 | for (UIViewController *viewController in self.childViewControllers) { 183 | [viewController viewDidAppear:animated]; 184 | } 185 | } 186 | 187 | isFirstViewDidAppear = NO; 188 | } 189 | 190 | #pragma mark - rotation 191 | 192 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 193 | // Return YES for supported orientations 194 | for (UIViewController *viewController in self.childViewControllers) { 195 | if (![viewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]) { 196 | return NO; 197 | } 198 | } 199 | return YES; 200 | } 201 | 202 | - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 203 | [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 204 | 205 | [self _willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 206 | } 207 | 208 | - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 209 | [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 210 | 211 | for (UIViewController *viewController in self.childViewControllers) { 212 | [viewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 213 | } 214 | } 215 | 216 | - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 217 | for (UIViewController *viewController in self.childViewControllers) { 218 | [viewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 219 | } 220 | } 221 | 222 | #pragma mark - private implementation 223 | 224 | - (void)updateBackgroundView { 225 | if (self.isViewLoaded) { 226 | _backgroundView.frame = self.view.bounds; 227 | _backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 228 | [self.view insertSubview:_backgroundView atIndex:0]; 229 | } 230 | } 231 | 232 | @end 233 | 234 | 235 | 236 | 237 | 238 | 239 | @implementation UIViewController (ANAdvancedNavigationController) 240 | 241 | - (ANAdvancedNavigationController *)advancedNavigationController { 242 | UIViewController *viewController = self.parentViewController; 243 | while (viewController != nil) { 244 | if ([viewController isKindOfClass:[ANAdvancedNavigationController class] ]) { 245 | return (ANAdvancedNavigationController *)viewController; 246 | } else { 247 | viewController = viewController.parentViewController; 248 | } 249 | } 250 | return nil; 251 | } 252 | 253 | @end 254 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANRectangleView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANRectangleView.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ANRectangleView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANRectangleView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANRectangleView.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANRectangleView.h" 10 | #import 11 | 12 | @implementation ANRectangleView 13 | 14 | - (id)initWithFrame:(CGRect)frame { 15 | if (self = [super initWithFrame:frame]) { 16 | // Initialization code 17 | self.backgroundColor = [UIColor clearColor]; 18 | self.layer.needsDisplayOnBoundsChange = YES; 19 | } 20 | return self; 21 | } 22 | 23 | // Only override drawRect: if you perform custom drawing. 24 | // An empty implementation adversely affects performance during animation. 25 | - (void)drawRect:(CGRect)rect { 26 | // Drawing code 27 | static CGFloat inset = 5.0f; 28 | UIBezierPath *roundRectPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, inset, inset) cornerRadius:10.0f]; 29 | [[UIColor colorWithWhite:0.0f alpha:0.25f] setFill]; 30 | 31 | [roundRectPath fill]; 32 | [[UIColor whiteColor] setStroke]; 33 | 34 | [roundRectPath setLineWidth:1.5f]; 35 | [roundRectPath stroke]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANRemoveRectangleIndicatorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANRemoveRectangleIndicatorView.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANRectangleView.h" 11 | 12 | typedef enum { 13 | ANRemoveRectangleIndicatorViewStateHidden = 0, 14 | ANRemoveRectangleIndicatorViewStateVisible, 15 | ANRemoveRectangleIndicatorViewStateFlippedToRight, 16 | ANRemoveRectangleIndicatorViewStateRemovedRight 17 | } ANRemoveRectangleIndicatorViewState; 18 | 19 | 20 | 21 | 22 | 23 | @interface ANRemoveRectangleIndicatorView : UIView { 24 | ANRectangleView *_firstRectangleView; 25 | ANRectangleView *_secondRectangleView; 26 | 27 | ANRemoveRectangleIndicatorViewState _state; 28 | 29 | CGPoint _secondRectangleViewCenterPoint; 30 | CGPoint _secondRectangleViewFlippedCenterPoint; 31 | CGPoint _secondRectangleViewRemovedCenterPoint; 32 | } 33 | 34 | @property (nonatomic, retain, readonly) ANRectangleView *firstRectangleView; 35 | @property (nonatomic, retain, readonly) ANRectangleView *secondRectangleView; 36 | 37 | @property (nonatomic, assign) ANRemoveRectangleIndicatorViewState state; 38 | - (void)setState:(ANRemoveRectangleIndicatorViewState)state animated:(BOOL)animated; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/ANRemoveRectangleIndicatorView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANRemoveRectangleIndicatorView.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANRemoveRectangleIndicatorView.h" 10 | 11 | static CGFloat kANRemoveRectangleIndicatorViewAnimationDuration = 0.15f; 12 | 13 | @implementation ANRemoveRectangleIndicatorView 14 | @synthesize firstRectangleView=_firstRectangleView, secondRectangleView=_secondRectangleView, state=_state; 15 | 16 | - (void)setState:(ANRemoveRectangleIndicatorViewState)state { 17 | [self setState:state animated:NO]; 18 | } 19 | 20 | - (void)setState:(ANRemoveRectangleIndicatorViewState)state animated:(BOOL)animated { 21 | if (state != _state) { 22 | __block CGFloat animationDuration = kANRemoveRectangleIndicatorViewAnimationDuration; 23 | void(^animationBlock)(void) = ^(void) { 24 | switch (state) { 25 | case ANRemoveRectangleIndicatorViewStateHidden: 26 | self.alpha = 0.0f; 27 | _secondRectangleView.center = _secondRectangleViewCenterPoint; 28 | _secondRectangleView.transform = CGAffineTransformIdentity; 29 | _secondRectangleView.alpha = 1.0f; 30 | break; 31 | case ANRemoveRectangleIndicatorViewStateVisible: 32 | self.alpha = 1.0f; 33 | _secondRectangleView.center = _secondRectangleViewCenterPoint; 34 | _secondRectangleView.transform = CGAffineTransformIdentity; 35 | _secondRectangleView.alpha = 1.0f; 36 | break; 37 | case ANRemoveRectangleIndicatorViewStateFlippedToRight: 38 | self.alpha = 1.0f; 39 | _secondRectangleView.center = _secondRectangleViewFlippedCenterPoint; 40 | _secondRectangleView.transform = CGAffineTransformMakeRotation(M_PI / 8.0f); 41 | _secondRectangleView.alpha = 0.5f; 42 | break; 43 | case ANRemoveRectangleIndicatorViewStateRemovedRight: 44 | self.alpha = 1.0f; 45 | _secondRectangleView.center = _secondRectangleViewRemovedCenterPoint; 46 | _secondRectangleView.transform = CGAffineTransformMakeRotation(M_PI / 2.0f); 47 | _secondRectangleView.alpha = 0.5f; 48 | break; 49 | default: 50 | break; 51 | } 52 | }; 53 | 54 | _state = state; 55 | if (animated) { 56 | [UIView animateWithDuration:animationDuration 57 | animations:animationBlock]; 58 | } else { 59 | animationBlock(); 60 | } 61 | } 62 | } 63 | 64 | - (id)initWithFrame:(CGRect)frame { 65 | if (self = [super initWithFrame:frame]) { 66 | // Initialization code 67 | static CGFloat topOffset = 20.0f; 68 | CGFloat width = CGRectGetWidth(self.bounds)/2.5f; 69 | self.backgroundColor = [UIColor clearColor]; 70 | _firstRectangleView = [[ANRectangleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, width, CGRectGetHeight(self.bounds)-topOffset)]; 71 | [self addSubview:_firstRectangleView]; 72 | 73 | _secondRectangleView = [[ANRectangleView alloc] initWithFrame:CGRectMake(width/2.0f, topOffset, width, CGRectGetHeight(self.bounds)-20.0f)]; 74 | _secondRectangleViewCenterPoint = _secondRectangleView.center; 75 | _secondRectangleViewFlippedCenterPoint = CGPointMake(_secondRectangleViewCenterPoint.x + 80.0f, _secondRectangleViewCenterPoint.y + 30.0f); 76 | _secondRectangleViewRemovedCenterPoint = CGPointMake(_secondRectangleViewFlippedCenterPoint.x + 10.0f, _secondRectangleViewFlippedCenterPoint.y + 150.0f); 77 | [self addSubview:_secondRectangleView]; 78 | 79 | self.state = ANRemoveRectangleIndicatorViewStateHidden; 80 | self.alpha = 0.0f; 81 | } 82 | return self; 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/ANAdvancedNavigationController+private.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+private.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController.h" 10 | #import 11 | #import "ANRemoveRectangleIndicatorView.h" 12 | 13 | extern const CGFloat ANAdvancedNavigationControllerDefaultAnimationDuration; 14 | extern const CGFloat ANAdvancedNavigationControllerDefaultDraggingDistance; 15 | 16 | @interface ANAdvancedNavigationController () { 17 | UIViewController *_leftViewController; 18 | UIView *_backgroundView; 19 | 20 | NSMutableArray *_viewControllers; 21 | 22 | CGFloat _draggingDistance; 23 | NSDate *_draggingStartDate; 24 | NSInteger _draggingRightAnchorViewControllerIndex; 25 | 26 | ANRemoveRectangleIndicatorView *_removeRectangleIndicatorView; 27 | 28 | id __weak _delegate; 29 | 30 | NSUInteger _indexOfFrontViewController; 31 | } 32 | 33 | - (void)updateBackgroundView; 34 | 35 | @property (nonatomic, retain) NSDate *draggingStartDate; 36 | 37 | @property (nonatomic, retain) NSMutableArray *viewControllers; 38 | 39 | @property (nonatomic, retain) ANRemoveRectangleIndicatorView *removeRectangleIndicatorView; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/LeftViewController/ANAdvancedNavigationController+LeftViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+LeftViewController.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewController) 13 | 14 | - (void)_setLeftViewController:(UIViewController *)leftViewController; 15 | - (void)_insertLeftViewControllerView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/LeftViewController/ANAdvancedNavigationController+LeftViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+LeftViewController.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController+LeftViewController.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewControllerPrivate) 13 | - (void)__removeLeftViewControllerView; 14 | - (void)__removeLeftViewController; 15 | @end 16 | 17 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewControllerPrivate) 18 | 19 | - (void)__removeLeftViewControllerView { 20 | if (self.isViewLoaded) { 21 | [_leftViewController viewWillDisappear:NO]; 22 | [_leftViewController.view removeFromSuperview]; 23 | [_leftViewController viewDidDisappear:NO]; 24 | } 25 | } 26 | 27 | - (void)__removeLeftViewController { 28 | [_leftViewController willMoveToParentViewController:nil]; 29 | if (self.isViewLoaded) { 30 | [self __removeLeftViewControllerView]; 31 | } 32 | [_leftViewController removeFromParentViewController]; 33 | _leftViewController = nil; 34 | } 35 | 36 | @end 37 | 38 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewController) 39 | 40 | - (void)_setLeftViewController:(UIViewController *)leftViewController { 41 | [self __removeLeftViewController]; 42 | 43 | if (leftViewController != nil) { 44 | _leftViewController = leftViewController; 45 | [self addChildViewController:leftViewController]; 46 | if (self.isViewLoaded) { 47 | [self _insertLeftViewControllerView]; 48 | } 49 | [_leftViewController didMoveToParentViewController:self]; 50 | } 51 | } 52 | 53 | - (void)_insertLeftViewControllerView { 54 | if (self.isViewLoaded) { 55 | _leftViewController.view.frame = CGRectMake(0.0f, 0.0f, ANAdvancedNavigationControllerDefaultLeftViewControllerWidth, CGRectGetHeight(self.view.bounds)); 56 | _leftViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight; 57 | [_leftViewController viewWillAppear:NO]; 58 | [self.view addSubview:_leftViewController.view]; 59 | [_leftViewController viewDidAppear:NO]; 60 | } 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers+Anchors.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers+Anchors.h 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Anchors) 13 | 14 | @property (nonatomic, readonly) CGFloat __minimumDragOffsetToShowRemoveInformation; 15 | 16 | // anchor points, at which the viewControllers views center will be layed out 17 | @property (nonatomic, readonly) CGFloat __anchorPortraitLeft; 18 | @property (nonatomic, readonly) CGFloat __anchorPortraitRight; 19 | @property (nonatomic, readonly) CGFloat __anchorLandscapeLeft; 20 | @property (nonatomic, readonly) CGFloat __anchorLandscapeMiddle; 21 | @property (nonatomic, readonly) CGFloat __anchorLandscapeRight; 22 | @property (nonatomic, readonly) CGFloat __leftAnchorForInterfaceOrientation; 23 | @property (nonatomic, readonly) CGFloat __rightAnchorForInterfaceOrientation; 24 | - (CGFloat)__leftAnchorForInterfaceOrientationAndRightViewController:(UIViewController *)rightViewController; 25 | 26 | - (CGPoint)__centerPointForRightViewController:(UIViewController *)rightViewController withIndexOfCurrentViewControllerAtRightAnchor:(NSUInteger)indexOfMostRightViewController; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers+Anchors.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers+Anchors.m 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController+RightViewControllers+Anchors.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | 12 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Anchors) 13 | 14 | - (CGFloat)__minimumDragOffsetToShowRemoveInformation { 15 | CGRect frame = self.removeRectangleIndicatorView.frame; 16 | return CGRectGetWidth(frame) + frame.origin.x + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f - 20.0f; 17 | } 18 | 19 | - (CGFloat)__leftBoundsPanningAnchor { 20 | // if we only have one viewController, we can pan infinite 21 | if (self.viewControllers.count <= 1) { 22 | return -CGFLOAT_MAX; 23 | } 24 | return ANAdvancedNavigationControllerDefaultLeftPanningOffset + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 25 | } 26 | 27 | - (CGFloat)__anchorPortraitLeft { 28 | return ANAdvancedNavigationControllerDefaultLeftPanningOffset + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 29 | } 30 | 31 | - (CGFloat)__anchorPortraitRight { 32 | return CGRectGetWidth(self.view.bounds) - ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 33 | } 34 | 35 | - (CGFloat)__anchorLandscapeLeft { 36 | return ANAdvancedNavigationControllerDefaultLeftPanningOffset + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 37 | } 38 | 39 | - (CGFloat)__anchorLandscapeMiddle { 40 | return ANAdvancedNavigationControllerDefaultLeftViewControllerWidth + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 41 | } 42 | 43 | - (CGFloat)__anchorLandscapeRight { 44 | return CGRectGetWidth(self.view.bounds) - ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 45 | } 46 | 47 | - (CGFloat)__leftAnchorForInterfaceOrientation { 48 | if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 49 | return self.__anchorPortraitLeft; 50 | } else { 51 | return self.__anchorLandscapeLeft; 52 | } 53 | } 54 | 55 | - (CGFloat)__rightAnchorForInterfaceOrientation { 56 | if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 57 | return self.__anchorPortraitRight; 58 | } else { 59 | return self.__anchorLandscapeRight; 60 | } 61 | } 62 | 63 | - (CGFloat)__leftAnchorForInterfaceOrientationAndRightViewController:(UIViewController *)rightViewController { 64 | CGFloat anchor = self.__leftAnchorForInterfaceOrientation; 65 | NSUInteger index = [self.viewControllers indexOfObject:rightViewController]; 66 | return anchor + index*2; 67 | } 68 | 69 | - (CGPoint)__centerPointForRightViewController:(UIViewController *)rightViewController 70 | withIndexOfCurrentViewControllerAtRightAnchor:(NSUInteger)indexOfMostRightViewController { 71 | 72 | if (![self.viewControllers containsObject:rightViewController]) { 73 | [NSException raise:NSInternalInconsistencyException format:@"rightViewController (%@) is not part of the viewController hierarchy", rightViewController]; 74 | } 75 | if (indexOfMostRightViewController >= self.viewControllers.count) { 76 | [NSException raise:NSInternalInconsistencyException format:@"indexOfMostRightViewController (%d) excedes number of ViewControllers (%d)", indexOfMostRightViewController, self.viewControllers.count]; 77 | } 78 | 79 | if (self.viewControllers.count <= 1) { // only one view controller 80 | CGFloat anchorPoint = 0.0; 81 | // move it to the right or to the middle based on interfaceOrientation 82 | if (UIDeviceOrientationIsPortrait(self.interfaceOrientation)) { 83 | anchorPoint = self.__anchorPortraitRight; 84 | } else { 85 | anchorPoint = self.__anchorLandscapeMiddle; 86 | } 87 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 88 | } 89 | 90 | // now we definetly have more that one viewController in our hierarchy 91 | NSUInteger indexOfRightViewController = [self.viewControllers indexOfObject:rightViewController]; 92 | 93 | if (indexOfRightViewController < indexOfMostRightViewController) { 94 | // the viewController needs to be put on our left stack 95 | return CGPointMake([self __leftAnchorForInterfaceOrientationAndRightViewController:rightViewController], CGRectGetHeight(self.view.bounds)/2.0f); 96 | } else if (indexOfRightViewController == indexOfMostRightViewController) { 97 | // this viewController must be pushed on our right site 98 | if (indexOfRightViewController == 0) { 99 | // its the first most down viewController 100 | CGFloat anchorPoint = 0.0f; 101 | // portrait -> move to left, landscape -> move to middle 102 | if (UIDeviceOrientationIsPortrait(self.interfaceOrientation)) { 103 | anchorPoint = self.__anchorPortraitRight; 104 | } else { 105 | anchorPoint = self.__anchorLandscapeMiddle; 106 | } 107 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 108 | } else { 109 | return CGPointMake(self.__rightAnchorForInterfaceOrientation, CGRectGetHeight(self.view.bounds)/2.0f); 110 | } 111 | } else { 112 | if (UIDeviceOrientationIsLandscape(self.interfaceOrientation) && indexOfMostRightViewController == 0) { 113 | // our most right one will be in the middle 114 | CGFloat anchorPoint = self.__anchorLandscapeMiddle + (CGFloat)(indexOfRightViewController - indexOfMostRightViewController) * ANAdvancedNavigationControllerDefaultDraggingDistance; 115 | 116 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 117 | } 118 | // this viewController is on the right site of our current active viewController 119 | CGFloat anchorPoint = self.__rightAnchorForInterfaceOrientation + (CGFloat)(indexOfRightViewController - indexOfMostRightViewController) * ANAdvancedNavigationControllerDefaultDraggingDistance; 120 | 121 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 122 | } 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers.h 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers) 13 | 14 | - (void)_pushViewController:(UIViewController *)viewController 15 | afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 16 | 17 | - (void)_popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated; 18 | 19 | - (void)_prepareViewForPanning; 20 | 21 | - (void)_willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; 22 | 23 | - (void)_insertRightViewControllerInDataModel:(UIViewController *)rightViewController; 24 | - (void)_insertRightViewControllerViews; 25 | 26 | - (void)_setIndexOfFrontViewController:(NSUInteger)indexOfFrontViewController; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ANAdvancedNavigationController/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers.m 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController+RightViewControllers.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | #import "ANAdvancedNavigationController+RightViewControllers+Anchors.h" 12 | #import 13 | 14 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Private) 15 | 16 | // inserting new viewControllers 17 | - (void)__pushRootViewController:(UIViewController *)rootViewController animated:(BOOL)animated; 18 | - (void)__pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 19 | 20 | // removing old viewControllers 21 | - (void)__removeRightViewController:(UIViewController *)rightViewController animated:(BOOL)animated; 22 | 23 | // concistency stuff 24 | - (void)__numberOfRightViewControllersDidChanged; 25 | - (void)__updateViewControllerShadows; 26 | 27 | // managing rightViewControllers views 28 | - (UIView *)__loadViewForNewRightViewController:(UIViewController *)rightViewController; 29 | - (UIView *)__viewForRightViewController:(UIViewController *)rightViewController; 30 | - (BOOL)__isRightViewControllerAlreayInViewHierarchy:(UIViewController *)rightViewController; 31 | - (void)__moveRightViewControllerToRightAnchorPoint:(UIViewController *)rightViewController animated:(BOOL)animated; 32 | 33 | // panning 34 | - (UIViewController *)__bestRightAnchorPointViewControllerWithIndex:(NSInteger *)index; 35 | - (void)__updateViewControllersWithTranslation:(CGFloat)translation; 36 | - (void)__mainPanGestureRecognizedDidRecognizePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer; 37 | 38 | - (void)__popViewControllersAfterDraggingFarToTheRight; 39 | 40 | @end 41 | 42 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Private) 43 | 44 | #pragma mark - inserting new viewControllers 45 | 46 | - (void)__pushRootViewController:(UIViewController *)rootViewController animated:(BOOL)animated { 47 | NSArray *oldViewControllers = [self.viewControllers copy]; 48 | 49 | [oldViewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 50 | [self __removeRightViewController:obj animated:animated]; 51 | }]; 52 | 53 | [self.viewControllers addObject:rootViewController]; 54 | [self addChildViewController:rootViewController]; 55 | [self __numberOfRightViewControllersDidChanged]; 56 | 57 | // now display the new rootViewController, if the view is loaded 58 | UIView *newView = [self __loadViewForNewRightViewController:rootViewController]; 59 | 60 | [rootViewController viewWillAppear:animated]; 61 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPushViewController:afterViewController:animated:)]) { 62 | [self.delegate advancedNavigationController:self willPushViewController:rootViewController afterViewController:nil animated:animated]; 63 | } 64 | if (newView) { 65 | newView.center = CGPointMake(CGRectGetWidth(self.view.bounds) + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f, CGRectGetHeight(self.view.bounds)/2.0f); 66 | [self.view addSubview:newView]; 67 | CGPoint nextCenterPoint = [self __centerPointForRightViewController:rootViewController withIndexOfCurrentViewControllerAtRightAnchor:0]; 68 | if (animated) { 69 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 70 | animations:^(void) { 71 | newView.center = nextCenterPoint; 72 | } 73 | completion:^(BOOL finished) { 74 | [rootViewController viewDidAppear:animated]; 75 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:afterViewController:animated:)]) { 76 | [self.delegate advancedNavigationController:self didPushViewController:rootViewController afterViewController:nil animated:animated]; 77 | } 78 | [rootViewController didMoveToParentViewController:self]; 79 | _indexOfFrontViewController = 0; 80 | }]; 81 | } else { 82 | newView.center = nextCenterPoint; 83 | [rootViewController viewDidAppear:animated]; 84 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:afterViewController:animated:)]) { 85 | [self.delegate advancedNavigationController:self didPushViewController:rootViewController afterViewController:nil animated:animated]; 86 | } 87 | [rootViewController didMoveToParentViewController:self]; 88 | _indexOfFrontViewController = 0; 89 | } 90 | } 91 | } 92 | 93 | - (void)__pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated { 94 | if ([self.viewControllers containsObject:viewController]) { 95 | NSLog(@"viewController (%@) is already part of the viewController Hierarchy", viewController); 96 | return; 97 | } 98 | if (![self.viewControllers containsObject:afterViewController]) { 99 | NSLog(@"afterViewController (%@) is not part of the viewController Hierarchy", afterViewController); 100 | } 101 | 102 | NSUInteger afterIndex = [self.viewControllers indexOfObject:afterViewController]+1; 103 | NSIndexSet *deleteIndexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(afterIndex, self.viewControllers.count - afterIndex)]; 104 | 105 | NSArray *oldViewControllers = [self.viewControllers objectsAtIndexes:deleteIndexSet]; 106 | 107 | // remove all viewControllers, that come after afterViewController 108 | [oldViewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 109 | [self __removeRightViewController:obj animated:animated]; 110 | }]; 111 | 112 | // insert viewController in data structure 113 | [self.viewControllers addObject:viewController]; 114 | [self addChildViewController:viewController]; 115 | [self __numberOfRightViewControllersDidChanged]; 116 | 117 | UIView *newView = [self __loadViewForNewRightViewController:viewController]; 118 | 119 | [viewController viewWillAppear:animated]; 120 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPushViewController:afterViewController:animated:)]) { 121 | [self.delegate advancedNavigationController:self willPushViewController:viewController afterViewController:afterViewController animated:animated]; 122 | } 123 | if (newView) { 124 | [self.view addSubview:newView]; 125 | newView.center = CGPointMake(CGRectGetWidth(self.view.bounds)+ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f, CGRectGetHeight(self.view.bounds)/2.0f); 126 | // now insert the new view into our view hirarchy 127 | if (animated) { 128 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 129 | animations:^(void) { 130 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 131 | UIView *view = [self __viewForRightViewController:obj]; 132 | view.center = [self __centerPointForRightViewController:obj 133 | withIndexOfCurrentViewControllerAtRightAnchor:self.viewControllers.count-1]; 134 | }]; 135 | } 136 | completion:^(BOOL finished) { 137 | [viewController viewDidAppear:animated]; 138 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:afterViewController:animated:)]) { 139 | [self.delegate advancedNavigationController:self didPushViewController:viewController afterViewController:afterViewController animated:animated]; 140 | } 141 | [viewController didMoveToParentViewController:self]; 142 | _indexOfFrontViewController = self.viewControllers.count-1; 143 | }]; 144 | } else { 145 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 146 | UIView *view = [self __viewForRightViewController:obj]; 147 | view.center = [self __centerPointForRightViewController:obj 148 | withIndexOfCurrentViewControllerAtRightAnchor:self.viewControllers.count-1]; 149 | }]; 150 | [viewController viewDidAppear:animated]; 151 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:animated:)]) { 152 | [self.delegate advancedNavigationController:self didPushViewController:viewController afterViewController:afterViewController animated:animated]; 153 | } 154 | [viewController didMoveToParentViewController:self]; 155 | _indexOfFrontViewController = self.viewControllers.count-1; 156 | } 157 | } 158 | } 159 | 160 | #pragma mark - removing old viewControllers 161 | 162 | - (void)__removeRightViewController:(UIViewController *)rightViewController animated:(BOOL)animated { 163 | if (![self.viewControllers containsObject:rightViewController]) { 164 | NSLog(@"rightViewController (%@) is not part of the viewController Hierarchy", rightViewController); 165 | return; 166 | } 167 | 168 | [rightViewController willMoveToParentViewController:nil]; 169 | 170 | [self.viewControllers removeObject:rightViewController]; 171 | [self __numberOfRightViewControllersDidChanged]; 172 | 173 | [rightViewController viewWillDisappear:animated]; 174 | UIView *view = [self __viewForRightViewController:rightViewController]; 175 | if (animated) { 176 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 177 | animations:^(void) { 178 | CGPoint center = view.center; 179 | center.x = CGRectGetWidth(self.view.bounds) + ANAdvancedNavigationControllerDefaultLeftViewControllerWidth; 180 | view.center = center; 181 | } 182 | completion:^(BOOL finished) { 183 | [view removeFromSuperview]; 184 | [rightViewController viewDidDisappear:animated]; 185 | [rightViewController removeFromParentViewController]; 186 | _indexOfFrontViewController = self.viewControllers.count-1; 187 | }]; 188 | } else { 189 | [view removeFromSuperview]; 190 | [rightViewController viewDidDisappear:animated]; 191 | [rightViewController removeFromParentViewController]; 192 | _indexOfFrontViewController = self.viewControllers.count-1; 193 | } 194 | } 195 | 196 | - (void)__popViewControllersAfterDraggingFarToTheRight { 197 | NSArray *oldArray = [self.viewControllers copy]; 198 | 199 | [oldArray enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 200 | if (idx > 0) { 201 | [self __removeRightViewController:obj animated:NO]; 202 | } 203 | }]; 204 | 205 | UIViewController *viewController = [self.viewControllers objectAtIndex:0]; 206 | 207 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPopToViewController:animated:)]) { 208 | [self.delegate advancedNavigationController:self willPopToViewController:viewController animated:YES]; 209 | } 210 | self.removeRectangleIndicatorView.state = ANRemoveRectangleIndicatorViewStateFlippedToRight; 211 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 212 | animations:^(void) { 213 | self.removeRectangleIndicatorView.state = ANRemoveRectangleIndicatorViewStateRemovedRight; 214 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:NO]; 215 | } 216 | completion:^(BOOL finished) { 217 | [self __numberOfRightViewControllersDidChanged]; 218 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPopToViewController:animated:)]) { 219 | [self.delegate advancedNavigationController:self didPopToViewController:viewController animated:YES]; 220 | } 221 | _indexOfFrontViewController = 0; 222 | }]; 223 | } 224 | 225 | #pragma mark - concistency stuff 226 | 227 | - (void)__numberOfRightViewControllersDidChanged { 228 | if (self.viewControllers.count <= 1) { 229 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateHidden animated:YES]; 230 | } else { 231 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateVisible animated:YES]; 232 | } 233 | } 234 | 235 | - (void)__updateViewControllerShadows { 236 | [self.viewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 237 | UIView *view = [self __viewForRightViewController:obj]; 238 | CALayer *layer = view.layer; 239 | layer.shadowPath = [UIBezierPath bezierPathWithRect:view.bounds].CGPath; 240 | }]; 241 | } 242 | 243 | #pragma mark - rightViewControllers views 244 | 245 | - (UIView *)__loadViewForNewRightViewController:(UIViewController *)rightViewController { 246 | if (!self.isViewLoaded) { 247 | return nil; 248 | } 249 | if (rightViewController.isViewLoaded) { 250 | if (rightViewController.view.superview) { 251 | return rightViewController.view.superview; 252 | } 253 | } 254 | UIView *wrapperView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, ANAdvancedNavigationControllerDefaultViewControllerWidth, CGRectGetHeight(self.view.bounds))]; 255 | wrapperView.backgroundColor = [UIColor blackColor]; 256 | 257 | rightViewController.view.frame = wrapperView.bounds; 258 | [wrapperView addSubview:rightViewController.view]; 259 | rightViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight; 260 | wrapperView.autoresizingMask = rightViewController.view.autoresizingMask; 261 | 262 | CALayer *layer = wrapperView.layer; 263 | layer.masksToBounds = NO; 264 | layer.shadowPath = [UIBezierPath bezierPathWithRect:rightViewController.view.bounds].CGPath; 265 | layer.shadowColor = [UIColor blackColor].CGColor; 266 | layer.shadowRadius = 15.0f; 267 | layer.shadowOpacity = 0.5f; 268 | layer.shadowOffset = CGSizeMake(0.0f, 0.0f); 269 | 270 | return wrapperView; 271 | } 272 | 273 | - (UIView *)__viewForRightViewController:(UIViewController *)rightViewController { 274 | if (!rightViewController.isViewLoaded) { 275 | return nil; 276 | } 277 | return rightViewController.view.superview; 278 | } 279 | 280 | - (BOOL)__isRightViewControllerAlreayInViewHierarchy:(UIViewController *)rightViewController { 281 | return [self __viewForRightViewController:rightViewController].superview == self.view; 282 | } 283 | 284 | - (void)__moveRightViewControllerToRightAnchorPoint:(UIViewController *)rightViewController animated:(BOOL)animated { 285 | NSUInteger rightViewControllerIndex = [self.viewControllers indexOfObject:rightViewController]; 286 | _indexOfFrontViewController = rightViewControllerIndex; 287 | _draggingRightAnchorViewControllerIndex = rightViewControllerIndex; 288 | 289 | if (animated) { 290 | UIView *rightViewControllerView = [self __viewForRightViewController:rightViewController]; 291 | CGPoint currentRightCenterPoint = rightViewControllerView.center; 292 | CGPoint finalRightCenterPoint = [self __centerPointForRightViewController:rightViewController withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 293 | 294 | CGFloat distance = (finalRightCenterPoint.x - currentRightCenterPoint.x)*0.05f; 295 | 296 | if (self.viewControllers.count == 1) { 297 | // well, we got only one viewController, just set this one to the center with a simple UIView-animation 298 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 299 | animations:^(void) { 300 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 301 | UIView *view = [self __viewForRightViewController:obj]; 302 | view.center = [self __centerPointForRightViewController:obj withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 303 | }]; 304 | }]; 305 | } else { 306 | // now we got more that one viewController, we need a little bounde animation 307 | 308 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 309 | UIView *view = [self __viewForRightViewController:obj]; 310 | CGPoint finalCenterPoint = [self __centerPointForRightViewController:obj withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 311 | 312 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"]; 313 | animation.calculationMode = kCAAnimationLinear; 314 | 315 | if (abs(idx - rightViewControllerIndex) <= 1 && finalCenterPoint.x+distance >= self.__leftAnchorForInterfaceOrientation) { 316 | animation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:view.center.x], 317 | [NSNumber numberWithFloat:finalCenterPoint.x], 318 | [NSNumber numberWithFloat:finalCenterPoint.x+distance], 319 | [NSNumber numberWithFloat:finalCenterPoint.x], 320 | nil]; 321 | } else { 322 | animation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:view.center.x], 323 | [NSNumber numberWithFloat:finalCenterPoint.x], 324 | [NSNumber numberWithFloat:finalCenterPoint.x], 325 | [NSNumber numberWithFloat:finalCenterPoint.x], 326 | nil]; 327 | } 328 | 329 | animation.duration = 0.5f; 330 | 331 | [view.layer addAnimation:animation forKey:nil]; 332 | view.layer.position = finalCenterPoint; 333 | }]; 334 | } 335 | } else { 336 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 337 | UIView *view = [self __viewForRightViewController:obj]; 338 | view.center = [self __centerPointForRightViewController:obj withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 339 | }]; 340 | } 341 | } 342 | 343 | #pragma mark - Panning 344 | 345 | - (UIViewController *)__bestRightAnchorPointViewControllerWithIndex:(NSInteger *)index { 346 | 347 | __block NSUInteger bestIndex = 0; 348 | __block CGFloat bestDistance = CGFLOAT_MAX; 349 | 350 | [self.viewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 351 | UIViewController *viewController = obj; 352 | UIView *view = [self __viewForRightViewController:viewController]; 353 | 354 | CGFloat distance = fabsf(view.center.x - self.__rightAnchorForInterfaceOrientation); 355 | if (distance <= bestDistance) { 356 | bestDistance = distance; 357 | bestIndex = idx; 358 | } 359 | }]; 360 | 361 | if (index) { 362 | *index = bestIndex; 363 | } 364 | 365 | if (bestIndex == NSNotFound) { 366 | return nil; 367 | } 368 | 369 | return [self.viewControllers objectAtIndex:bestIndex]; 370 | } 371 | 372 | - (void)__updateViewControllersWithTranslation:(CGFloat)translation { 373 | NSUInteger count = self.viewControllers.count; 374 | 375 | CGFloat minDragOffsetToShowRemoveInformation = self.__minimumDragOffsetToShowRemoveInformation; 376 | __block UIViewController *previousViewController = nil; 377 | [self.viewControllers enumerateObjectsWithOptions:NSEnumerationReverse 378 | usingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 379 | UIViewController *currentViewController = obj; 380 | UIView *view = [self __viewForRightViewController:currentViewController]; 381 | 382 | CGPoint currentCenter = view.center; 383 | CGFloat leftBounds = [self __leftAnchorForInterfaceOrientationAndRightViewController:currentViewController]; 384 | 385 | if (currentCenter.x + translation < leftBounds) { 386 | currentCenter.x = leftBounds; 387 | } else { 388 | if ([self __viewForRightViewController:previousViewController].center.x - currentCenter.x >= ANAdvancedNavigationControllerDefaultDraggingDistance || !previousViewController || translation < 0.0f) { 389 | currentCenter.x += translation; 390 | } 391 | } 392 | 393 | view.center = currentCenter; 394 | 395 | previousViewController = currentViewController; 396 | 397 | if (count > 1 && idx == 0) { 398 | // first viewController has moved enough to the right 399 | if (currentCenter.x > minDragOffsetToShowRemoveInformation) { 400 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateFlippedToRight animated:YES]; 401 | } else { 402 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateVisible animated:YES]; 403 | } 404 | } 405 | }]; 406 | } 407 | 408 | - (void)__mainPanGestureRecognizedDidRecognizePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { 409 | if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { 410 | _draggingDistance = 0.0f; 411 | self.draggingStartDate = [NSDate date]; 412 | } else if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { 413 | // changed 414 | CGFloat translation = [panGestureRecognizer translationInView:self.view].x; 415 | [panGestureRecognizer setTranslation:CGPointZero inView:self.view]; 416 | 417 | if (self.viewControllers.count == 1) { 418 | translation /= 2.0f; 419 | } 420 | 421 | _draggingDistance += translation; 422 | 423 | [self __updateViewControllersWithTranslation:translation]; 424 | } else if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { 425 | // check, if we need to pop every viewController except the first one 426 | BOOL didPopViewControllers = NO; 427 | if (self.viewControllers.count > 1) { 428 | UIViewController *firstViewController = [self.viewControllers objectAtIndex:0]; 429 | UIView *view = [self __viewForRightViewController:firstViewController]; 430 | if (view.center.x > self.__minimumDragOffsetToShowRemoveInformation) { 431 | didPopViewControllers = YES; 432 | [self __popViewControllersAfterDraggingFarToTheRight]; 433 | } 434 | } 435 | 436 | if (self.viewControllers.count > 0 && !didPopViewControllers) { 437 | NSDate *now = [NSDate date]; 438 | CGFloat draggingTimeInterval = [now timeIntervalSinceDate:self.draggingStartDate]; 439 | // find that view controller, that is the best for the right anchor position 440 | NSInteger index = 0; 441 | UIViewController *viewController = [self __bestRightAnchorPointViewControllerWithIndex:&index]; 442 | if (viewController) { 443 | if (_draggingRightAnchorViewControllerIndex == index && draggingTimeInterval < 0.5f) { 444 | // we did "swipe", just move the next viewController in that direction in 445 | if (_draggingDistance > 0.0f) { 446 | index--; 447 | } else { 448 | index++; 449 | } 450 | 451 | if (index < 0) { 452 | index = 0; 453 | } else if (index >= self.viewControllers.count) { 454 | index = self.viewControllers.count-1; 455 | } 456 | viewController = [self.viewControllers objectAtIndex:index]; 457 | } 458 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:YES]; 459 | } 460 | } 461 | 462 | _draggingDistance = 0.0f; 463 | self.draggingStartDate = nil; 464 | } 465 | } 466 | 467 | @end 468 | 469 | 470 | 471 | 472 | 473 | 474 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers) 475 | 476 | #pragma setters and getters 477 | 478 | - (void)_setIndexOfFrontViewController:(NSUInteger)indexOfFrontViewController { 479 | if (!(indexOfFrontViewController < self.viewControllers.count)) { 480 | NSLog(@"indexOfFrontViewController (%d) exceeds viewControllers bounds (%d)", indexOfFrontViewController, self.viewControllers.count); 481 | return; 482 | } 483 | 484 | if (indexOfFrontViewController != _indexOfFrontViewController) { 485 | _indexOfFrontViewController = indexOfFrontViewController; 486 | 487 | if (self.isViewLoaded) { 488 | [self __moveRightViewControllerToRightAnchorPoint:[self.viewControllers objectAtIndex:_indexOfFrontViewController] animated:NO]; 489 | } 490 | } 491 | } 492 | 493 | #pragma mark - Pushing and poping 494 | 495 | - (void)_pushViewController:(UIViewController *)viewController 496 | afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated { 497 | // first lets do some concistency checks 498 | if ([self.viewControllers containsObject:viewController] || _leftViewController == viewController) { 499 | // viewController cant be part of the current viewController hierarchy 500 | NSLog(@"viewController (%@) is already part of the viewController Hierarchy", viewController); 501 | return; 502 | } 503 | if (![self.viewControllers containsObject:afterViewController] && afterViewController != nil) { 504 | NSLog(@"afterViewController (%@) is not part of the viewController Hierarchy", afterViewController); 505 | return; 506 | } 507 | 508 | if (afterViewController == _leftViewController) { 509 | afterViewController = nil; 510 | } 511 | 512 | if (afterViewController == nil) { 513 | // we need to push a new rootViewController 514 | [self __pushRootViewController:viewController animated:animated]; 515 | } else { 516 | [self __pushViewController:viewController afterViewController:afterViewController animated:animated]; 517 | } 518 | 519 | _draggingRightAnchorViewControllerIndex = [self.viewControllers indexOfObject:viewController]; 520 | } 521 | 522 | - (void)_popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated { 523 | if (![self.viewControllers containsObject:viewController]) { 524 | NSLog(@"viewController (%@) is not part of the viewController Hierarchy", viewController); 525 | return; 526 | } 527 | 528 | NSArray *oldArray = [self.viewControllers copy]; 529 | 530 | NSInteger index = [self.viewControllers indexOfObject:viewController]+1; 531 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPopToViewController:animated:)]) { 532 | [self.delegate advancedNavigationController:self willPopToViewController:viewController animated:animated]; 533 | } 534 | if (animated) { 535 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 536 | animations:^(void) { 537 | [oldArray enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, self.viewControllers.count-index)] 538 | options:NSEnumerationConcurrent 539 | usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 540 | [self __removeRightViewController:obj animated:NO]; 541 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:NO]; 542 | }]; 543 | } 544 | completion:^(BOOL finished) { 545 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPopToViewController:animated:)]) { 546 | [self.delegate advancedNavigationController:self didPopToViewController:viewController animated:animated]; 547 | } 548 | }]; 549 | } else { 550 | [oldArray enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, self.viewControllers.count-index)] 551 | options:NSEnumerationConcurrent 552 | usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 553 | [self __removeRightViewController:obj animated:NO]; 554 | }]; 555 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:NO]; 556 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPopToViewController:animated:)]) { 557 | [self.delegate advancedNavigationController:self didPopToViewController:viewController animated:animated]; 558 | } 559 | } 560 | } 561 | 562 | - (void)_prepareViewForPanning { 563 | UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(__mainPanGestureRecognizedDidRecognizePanGesture:)]; 564 | recognizer.maximumNumberOfTouches = 1; 565 | [self.view addGestureRecognizer:recognizer]; 566 | } 567 | 568 | - (void)_willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 569 | for (UIViewController *viewController in self.childViewControllers) { 570 | [viewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 571 | } 572 | [self __updateViewControllerShadows]; 573 | 574 | if (self.viewControllers.count > _draggingRightAnchorViewControllerIndex) { 575 | [self __moveRightViewControllerToRightAnchorPoint:[self.viewControllers objectAtIndex:_draggingRightAnchorViewControllerIndex] animated:NO]; 576 | } 577 | } 578 | 579 | - (void)_insertRightViewControllerInDataModel:(UIViewController *)rightViewController { 580 | [self.viewControllers addObject:rightViewController]; 581 | [self addChildViewController:rightViewController]; 582 | [self __numberOfRightViewControllersDidChanged]; 583 | } 584 | 585 | - (void)_insertRightViewControllerViews { 586 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 587 | if (![self __isRightViewControllerAlreayInViewHierarchy:obj]) { 588 | UIViewController *viewController = obj; 589 | UIView *view = [self __loadViewForNewRightViewController:viewController]; 590 | [viewController viewWillAppear:NO]; 591 | [self.view addSubview:view]; 592 | view.center = CGPointZero; 593 | [viewController viewDidAppear:NO]; 594 | } 595 | }]; 596 | if (_indexOfFrontViewController < self.viewControllers.count) { 597 | [self __moveRightViewControllerToRightAnchorPoint:[self.viewControllers objectAtIndex:_indexOfFrontViewController] animated:NO]; 598 | 599 | [self __updateViewControllerShadows]; 600 | } 601 | } 602 | 603 | @end 604 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Oliver Letterer 2 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 3 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 4 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ANAdvancedNavigationController 2 | 3 | **ANAdvancedNavigationController** is a subclass of *UIViewController* and works as a parent view controller. 4 | 5 | ## Setup ANAdvancedNavigationController for your project 6 | 7 | * add **ANAdvancedNavigationController** as a static Library to your project 8 | 9 | ## How to use ANAdvancedNavigationController 10 | 11 | ### Setup an instance of ANAdvancedNavigationController 12 | 13 | ```objective-c 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | // create the viewControllers that are displayed 16 | UIViewController *leftViewController = ...; 17 | 18 | // create an instance of ANAdvancedNavigationController 19 | ANAdvancedNavigationController *navigationController = [[ANAdvancedNavigationController alloc] initWithLeftViewController:leftViewController]; 20 | 21 | // set your instance of ANAdvancedNavigationController as your applicationDelegates rootViewController 22 | self.window.rootViewController = navigationController; 23 | 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | ``` 28 | 29 | ### Push a view controller 30 | 31 | To push a viewController, simply call 32 | 33 | ```objective-c 34 | - (void)pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 35 | ``` 36 | 37 | * `viewController`: the view controller, that will be pushed 38 | * `afterViewController`: the view controller, after which `viewController` should appear. **Note**: if `afterViewController` is `nil`, all right view controllers will be popped and `viewController` will be the first on the stack. 39 | * `animated`: push animated or not 40 | 41 | *Sample*: 42 | 43 | ```objective-c 44 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 45 | UIViewController *nextViewController = ...; 46 | [self.advancedNavigationController pushViewController:nextViewController afterViewController:self animated:YES]; 47 | } 48 | ``` 49 | 50 | ## Screenshots in my application [iHub - Social Coding](http://itunes.apple.com/de/app/ihub-social-coding/id433507459?mt=8) 51 | 52 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A7B6544513EA9143009E4414 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7B6544413EA9143009E4414 /* QuartzCore.framework */; }; 11 | A7C3773613EA8EF800B9943A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7C3773513EA8EF800B9943A /* Foundation.framework */; }; 12 | A7C3775313EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774213EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch */; }; 13 | A7C3775413EA8F2500B9943A /* ANAdvancedNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774313EA8F2500B9943A /* ANAdvancedNavigationController.h */; }; 14 | A7C3775513EA8F2500B9943A /* ANAdvancedNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774413EA8F2500B9943A /* ANAdvancedNavigationController.m */; }; 15 | A7C3775613EA8F2500B9943A /* ANRectangleView.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774513EA8F2500B9943A /* ANRectangleView.h */; }; 16 | A7C3775713EA8F2500B9943A /* ANRectangleView.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774613EA8F2500B9943A /* ANRectangleView.m */; }; 17 | A7C3775813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774713EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h */; }; 18 | A7C3775913EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m */; }; 19 | A7C3775A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h */; }; 20 | A7C3775B13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h */; }; 21 | A7C3775C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3774D13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m */; }; 22 | A7C3775D13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3774F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h */; }; 23 | A7C3775E13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3775013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m */; }; 24 | A7C3775F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C3775113EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h */; }; 25 | A7C3776013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = A7C3775213EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | A7B6544413EA9143009E4414 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 30 | A7C3773213EA8EF800B9943A /* libANAdvancedNavigationController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libANAdvancedNavigationController.a; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | A7C3773513EA8EF800B9943A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 32 | A7C3773913EA8EF800B9943A /* ANAdvancedNavigationController-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController-Prefix.pch"; sourceTree = ""; }; 33 | A7C3774213EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController-Prefix.pch"; sourceTree = ""; }; 34 | A7C3774313EA8F2500B9943A /* ANAdvancedNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANAdvancedNavigationController.h; sourceTree = ""; }; 35 | A7C3774413EA8F2500B9943A /* ANAdvancedNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANAdvancedNavigationController.m; sourceTree = ""; }; 36 | A7C3774513EA8F2500B9943A /* ANRectangleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANRectangleView.h; sourceTree = ""; }; 37 | A7C3774613EA8F2500B9943A /* ANRectangleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANRectangleView.m; sourceTree = ""; }; 38 | A7C3774713EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANRemoveRectangleIndicatorView.h; sourceTree = ""; }; 39 | A7C3774813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANRemoveRectangleIndicatorView.m; sourceTree = ""; }; 40 | A7C3774A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+private.h"; sourceTree = ""; }; 41 | A7C3774C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+LeftViewController.h"; sourceTree = ""; }; 42 | A7C3774D13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ANAdvancedNavigationController+LeftViewController.m"; sourceTree = ""; }; 43 | A7C3774F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+RightViewControllers+Anchors.h"; sourceTree = ""; }; 44 | A7C3775013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ANAdvancedNavigationController+RightViewControllers+Anchors.m"; sourceTree = ""; }; 45 | A7C3775113EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ANAdvancedNavigationController+RightViewControllers.h"; sourceTree = ""; }; 46 | A7C3775213EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ANAdvancedNavigationController+RightViewControllers.m"; sourceTree = ""; }; 47 | /* End PBXFileReference section */ 48 | 49 | /* Begin PBXFrameworksBuildPhase section */ 50 | A7C3772F13EA8EF800B9943A /* Frameworks */ = { 51 | isa = PBXFrameworksBuildPhase; 52 | buildActionMask = 2147483647; 53 | files = ( 54 | A7B6544513EA9143009E4414 /* QuartzCore.framework in Frameworks */, 55 | A7C3773613EA8EF800B9943A /* Foundation.framework in Frameworks */, 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXFrameworksBuildPhase section */ 60 | 61 | /* Begin PBXGroup section */ 62 | A7C3772713EA8EF800B9943A = { 63 | isa = PBXGroup; 64 | children = ( 65 | A7C3773713EA8EF800B9943A /* ANAdvancedNavigationController */, 66 | A7C3773413EA8EF800B9943A /* Frameworks */, 67 | A7C3773313EA8EF800B9943A /* Products */, 68 | ); 69 | sourceTree = ""; 70 | }; 71 | A7C3773313EA8EF800B9943A /* Products */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | A7C3773213EA8EF800B9943A /* libANAdvancedNavigationController.a */, 75 | ); 76 | name = Products; 77 | sourceTree = ""; 78 | }; 79 | A7C3773413EA8EF800B9943A /* Frameworks */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | A7B6544413EA9143009E4414 /* QuartzCore.framework */, 83 | A7C3773513EA8EF800B9943A /* Foundation.framework */, 84 | ); 85 | name = Frameworks; 86 | sourceTree = ""; 87 | }; 88 | A7C3773713EA8EF800B9943A /* ANAdvancedNavigationController */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | A7C3774213EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch */, 92 | A7C3774313EA8F2500B9943A /* ANAdvancedNavigationController.h */, 93 | A7C3774413EA8F2500B9943A /* ANAdvancedNavigationController.m */, 94 | A7C3774513EA8F2500B9943A /* ANRectangleView.h */, 95 | A7C3774613EA8F2500B9943A /* ANRectangleView.m */, 96 | A7C3774713EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h */, 97 | A7C3774813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m */, 98 | A7C3774913EA8F2500B9943A /* Private */, 99 | A7C3773813EA8EF800B9943A /* Supporting Files */, 100 | ); 101 | path = ANAdvancedNavigationController; 102 | sourceTree = ""; 103 | }; 104 | A7C3773813EA8EF800B9943A /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | A7C3773913EA8EF800B9943A /* ANAdvancedNavigationController-Prefix.pch */, 108 | ); 109 | name = "Supporting Files"; 110 | sourceTree = ""; 111 | }; 112 | A7C3774913EA8F2500B9943A /* Private */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | A7C3774A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h */, 116 | A7C3774B13EA8F2500B9943A /* LeftViewController */, 117 | A7C3774E13EA8F2500B9943A /* RightViewControllers */, 118 | ); 119 | path = Private; 120 | sourceTree = ""; 121 | }; 122 | A7C3774B13EA8F2500B9943A /* LeftViewController */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | A7C3774C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h */, 126 | A7C3774D13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m */, 127 | ); 128 | path = LeftViewController; 129 | sourceTree = ""; 130 | }; 131 | A7C3774E13EA8F2500B9943A /* RightViewControllers */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | A7C3774F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h */, 135 | A7C3775013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m */, 136 | A7C3775113EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h */, 137 | A7C3775213EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m */, 138 | ); 139 | path = RightViewControllers; 140 | sourceTree = ""; 141 | }; 142 | /* End PBXGroup section */ 143 | 144 | /* Begin PBXHeadersBuildPhase section */ 145 | A7C3773013EA8EF800B9943A /* Headers */ = { 146 | isa = PBXHeadersBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | A7C3775313EA8F2500B9943A /* ANAdvancedNavigationController-Prefix.pch in Headers */, 150 | A7C3775413EA8F2500B9943A /* ANAdvancedNavigationController.h in Headers */, 151 | A7C3775613EA8F2500B9943A /* ANRectangleView.h in Headers */, 152 | A7C3775813EA8F2500B9943A /* ANRemoveRectangleIndicatorView.h in Headers */, 153 | A7C3775A13EA8F2500B9943A /* ANAdvancedNavigationController+private.h in Headers */, 154 | A7C3775B13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.h in Headers */, 155 | A7C3775D13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.h in Headers */, 156 | A7C3775F13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.h in Headers */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXHeadersBuildPhase section */ 161 | 162 | /* Begin PBXNativeTarget section */ 163 | A7C3773113EA8EF800B9943A /* ANAdvancedNavigationController */ = { 164 | isa = PBXNativeTarget; 165 | buildConfigurationList = A7C3773F13EA8EF800B9943A /* Build configuration list for PBXNativeTarget "ANAdvancedNavigationController" */; 166 | buildPhases = ( 167 | A7C3772E13EA8EF800B9943A /* Sources */, 168 | A7C3772F13EA8EF800B9943A /* Frameworks */, 169 | A7C3773013EA8EF800B9943A /* Headers */, 170 | ); 171 | buildRules = ( 172 | ); 173 | dependencies = ( 174 | ); 175 | name = ANAdvancedNavigationController; 176 | productName = ANAdvancedNavigationController; 177 | productReference = A7C3773213EA8EF800B9943A /* libANAdvancedNavigationController.a */; 178 | productType = "com.apple.product-type.library.static"; 179 | }; 180 | /* End PBXNativeTarget section */ 181 | 182 | /* Begin PBXProject section */ 183 | A7C3772913EA8EF800B9943A /* Project object */ = { 184 | isa = PBXProject; 185 | attributes = { 186 | LastUpgradeCheck = 0420; 187 | ORGANIZATIONNAME = Home; 188 | }; 189 | buildConfigurationList = A7C3772C13EA8EF800B9943A /* Build configuration list for PBXProject "ANAdvancedNavigationController" */; 190 | compatibilityVersion = "Xcode 3.2"; 191 | developmentRegion = English; 192 | hasScannedForEncodings = 0; 193 | knownRegions = ( 194 | en, 195 | ); 196 | mainGroup = A7C3772713EA8EF800B9943A; 197 | productRefGroup = A7C3773313EA8EF800B9943A /* Products */; 198 | projectDirPath = ""; 199 | projectRoot = ""; 200 | targets = ( 201 | A7C3773113EA8EF800B9943A /* ANAdvancedNavigationController */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXSourcesBuildPhase section */ 207 | A7C3772E13EA8EF800B9943A /* Sources */ = { 208 | isa = PBXSourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | A7C3775513EA8F2500B9943A /* ANAdvancedNavigationController.m in Sources */, 212 | A7C3775713EA8F2500B9943A /* ANRectangleView.m in Sources */, 213 | A7C3775913EA8F2500B9943A /* ANRemoveRectangleIndicatorView.m in Sources */, 214 | A7C3775C13EA8F2500B9943A /* ANAdvancedNavigationController+LeftViewController.m in Sources */, 215 | A7C3775E13EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers+Anchors.m in Sources */, 216 | A7C3776013EA8F2500B9943A /* ANAdvancedNavigationController+RightViewControllers.m in Sources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXSourcesBuildPhase section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | A7C3773D13EA8EF800B9943A /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 228 | CLANG_ENABLE_OBJC_ARC = YES; 229 | COPY_PHASE_STRIP = NO; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_DYNAMIC_NO_PIC = NO; 232 | GCC_OPTIMIZATION_LEVEL = 0; 233 | GCC_PREPROCESSOR_DEFINITIONS = ( 234 | "DEBUG=1", 235 | "$(inherited)", 236 | ); 237 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 238 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 239 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 240 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 241 | GCC_WARN_UNUSED_VARIABLE = YES; 242 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 243 | SDKROOT = iphoneos; 244 | }; 245 | name = Debug; 246 | }; 247 | A7C3773E13EA8EF800B9943A /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | ALWAYS_SEARCH_USER_PATHS = NO; 251 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 252 | CLANG_ENABLE_OBJC_ARC = YES; 253 | COPY_PHASE_STRIP = YES; 254 | GCC_C_LANGUAGE_STANDARD = gnu99; 255 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 256 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 257 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 260 | SDKROOT = iphoneos; 261 | VALIDATE_PRODUCT = YES; 262 | }; 263 | name = Release; 264 | }; 265 | A7C3774013EA8EF800B9943A /* Debug */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | DSTROOT = /tmp/ANAdvancedNavigationController.dst; 269 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 270 | GCC_PREFIX_HEADER = "ANAdvancedNavigationController/ANAdvancedNavigationController-Prefix.pch"; 271 | OTHER_LDFLAGS = "-ObjC"; 272 | PRODUCT_NAME = "$(TARGET_NAME)"; 273 | SKIP_INSTALL = YES; 274 | }; 275 | name = Debug; 276 | }; 277 | A7C3774113EA8EF800B9943A /* Release */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | DSTROOT = /tmp/ANAdvancedNavigationController.dst; 281 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 282 | GCC_PREFIX_HEADER = "ANAdvancedNavigationController/ANAdvancedNavigationController-Prefix.pch"; 283 | OTHER_LDFLAGS = "-ObjC"; 284 | PRODUCT_NAME = "$(TARGET_NAME)"; 285 | SKIP_INSTALL = YES; 286 | }; 287 | name = Release; 288 | }; 289 | /* End XCBuildConfiguration section */ 290 | 291 | /* Begin XCConfigurationList section */ 292 | A7C3772C13EA8EF800B9943A /* Build configuration list for PBXProject "ANAdvancedNavigationController" */ = { 293 | isa = XCConfigurationList; 294 | buildConfigurations = ( 295 | A7C3773D13EA8EF800B9943A /* Debug */, 296 | A7C3773E13EA8EF800B9943A /* Release */, 297 | ); 298 | defaultConfigurationIsVisible = 0; 299 | defaultConfigurationName = Release; 300 | }; 301 | A7C3773F13EA8EF800B9943A /* Build configuration list for PBXNativeTarget "ANAdvancedNavigationController" */ = { 302 | isa = XCConfigurationList; 303 | buildConfigurations = ( 304 | A7C3774013EA8EF800B9943A /* Debug */, 305 | A7C3774113EA8EF800B9943A /* Release */, 306 | ); 307 | defaultConfigurationIsVisible = 0; 308 | defaultConfigurationName = Release; 309 | }; 310 | /* End XCConfigurationList section */ 311 | }; 312 | rootObject = A7C3772913EA8EF800B9943A /* Project object */; 313 | } 314 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANAdvancedNavigationController-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ANAdvancedNavigationController' target in the 'ANAdvancedNavigationController' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANAdvancedNavigationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern const CGFloat ANAdvancedNavigationControllerDefaultLeftViewControllerWidth; 12 | extern const CGFloat ANAdvancedNavigationControllerDefaultViewControllerWidth; 13 | extern const CGFloat ANAdvancedNavigationControllerDefaultLeftPanningOffset; 14 | 15 | @class ANAdvancedNavigationController; 16 | 17 | 18 | 19 | @protocol ANAdvancedNavigationControllerDelegate 20 | 21 | @optional 22 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController willPushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 23 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController didPushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 24 | 25 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController willPopToViewController:(UIViewController *)viewController animated:(BOOL)animated; 26 | - (void)advancedNavigationController:(ANAdvancedNavigationController *)navigationController didPopToViewController:(UIViewController *)viewController animated:(BOOL)animated; 27 | 28 | @end 29 | 30 | 31 | 32 | 33 | 34 | @interface ANAdvancedNavigationController : UIViewController 35 | 36 | @property (nonatomic, retain) UIView *backgroundView; 37 | @property (nonatomic, retain) UIViewController *leftViewController; 38 | @property (nonatomic, readonly, copy) NSArray *rightViewControllers; 39 | 40 | @property (nonatomic, weak) id delegate; 41 | 42 | - (id)initWithLeftViewController:(UIViewController *)leftViewController; 43 | - (id)initWithLeftViewController:(UIViewController *)leftViewController rightViewControllers:(NSArray *)rightViewControllers; 44 | 45 | - (void)popViewController:(UIViewController *)viewController animated:(BOOL)animated; 46 | - (void)popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated; 47 | 48 | - (void)pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 49 | 50 | // will set/return the viewController, that is on anchor point right 51 | @property (nonatomic, assign) NSUInteger indexOfFrontViewController; 52 | 53 | @end 54 | 55 | 56 | 57 | 58 | @interface UIViewController (ANAdvancedNavigationController) 59 | @property (nonatomic, readonly) ANAdvancedNavigationController *advancedNavigationController; 60 | @end 61 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANAdvancedNavigationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | #import "ANAdvancedNavigationController+LeftViewController.h" 12 | #import "ANAdvancedNavigationController+RightViewControllers.h" 13 | #import 14 | 15 | const CGFloat ANAdvancedNavigationControllerDefaultLeftViewControllerWidth = 291.0f; 16 | const CGFloat ANAdvancedNavigationControllerDefaultViewControllerWidth = 475.0f; 17 | const CGFloat ANAdvancedNavigationControllerDefaultLeftPanningOffset = 75.0f; 18 | 19 | const CGFloat ANAdvancedNavigationControllerDefaultAnimationDuration = 0.35f; 20 | const CGFloat ANAdvancedNavigationControllerDefaultDraggingDistance = 473.0f; 21 | 22 | @implementation ANAdvancedNavigationController 23 | 24 | @synthesize backgroundView=_backgroundView; 25 | @synthesize leftViewController=_leftViewController, viewControllers=_viewControllers, removeRectangleIndicatorView=_removeRectangleIndicatorView; 26 | @synthesize delegate=_delegate; 27 | @synthesize draggingStartDate=_draggingStartDate; 28 | 29 | #pragma mark - setters and getters 30 | 31 | - (void)setLeftViewController:(UIViewController *)leftViewController { 32 | if (_leftViewController != leftViewController) { 33 | [self _setLeftViewController:leftViewController]; 34 | } 35 | } 36 | 37 | - (void)setBackgroundView:(UIView *)backgroundView { 38 | if (backgroundView != _backgroundView) { 39 | [_backgroundView removeFromSuperview]; 40 | _backgroundView = backgroundView; 41 | [self updateBackgroundView]; 42 | } 43 | } 44 | 45 | - (NSArray *)rightViewControllers { 46 | return [_viewControllers copy]; 47 | } 48 | 49 | - (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { 50 | return NO; 51 | } 52 | 53 | - (NSUInteger)indexOfFrontViewController { 54 | return _indexOfFrontViewController; 55 | } 56 | 57 | - (void)setIndexOfFrontViewController:(NSUInteger)indexOfFrontViewController { 58 | [self _setIndexOfFrontViewController:indexOfFrontViewController]; 59 | } 60 | 61 | #pragma mark - initialization 62 | 63 | - (id)init { 64 | if ((self = [super init])) { 65 | if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) { 66 | [NSException raise:NSInternalInconsistencyException format:@"ANAdvancedNavigationController is only supposed to work on iPad"]; 67 | } 68 | self.viewControllers = [NSMutableArray array]; 69 | } 70 | return self; 71 | } 72 | 73 | - (id)initWithLeftViewController:(UIViewController *)leftViewController { 74 | if ((self = [self init])) { 75 | self.leftViewController = leftViewController; 76 | } 77 | return self; 78 | } 79 | 80 | - (id)initWithLeftViewController:(UIViewController *)leftViewController rightViewControllers:(NSArray *)rightViewControllers { 81 | if (self = [self initWithLeftViewController:leftViewController]) { 82 | [rightViewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 83 | [self _insertRightViewControllerInDataModel:obj]; 84 | }]; 85 | } 86 | return self; 87 | } 88 | 89 | #pragma mark - Pushing and Poping 90 | 91 | - (void)popViewController:(UIViewController *)viewController animated:(BOOL)animated { 92 | if (![self.viewControllers containsObject:viewController]) { 93 | NSLog(@"viewController (%@) is not part of the viewController Hierarchy", viewController); 94 | return; 95 | } 96 | 97 | NSInteger index = [self.viewControllers indexOfObject:viewController]-1; 98 | 99 | if (index >= 0) { 100 | viewController = [self.viewControllers objectAtIndex:index]; 101 | [self _popViewControllersToViewController:viewController animated:animated]; 102 | } 103 | } 104 | 105 | - (void)popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated { 106 | [self _popViewControllersToViewController:viewController animated:animated]; 107 | } 108 | 109 | - (void)pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated { 110 | [self _pushViewController:viewController afterViewController:afterViewController animated:animated]; 111 | } 112 | 113 | #pragma mark - View lifecycle 114 | 115 | - (void)loadView { 116 | [super loadView]; 117 | 118 | CGFloat removeHeight = 75.0f; 119 | self.removeRectangleIndicatorView = [[ANRemoveRectangleIndicatorView alloc] initWithFrame:CGRectMake(ANAdvancedNavigationControllerDefaultLeftViewControllerWidth + 5.0f, CGRectGetHeight(self.view.bounds)/2.0f-removeHeight, 175.0f, removeHeight*2.0f)]; 120 | self.removeRectangleIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 121 | [self.view insertSubview:self.removeRectangleIndicatorView atIndex:0]; 122 | } 123 | 124 | - (void)viewDidLoad { 125 | [super viewDidLoad]; 126 | 127 | self.view.backgroundColor = [UIColor darkGrayColor]; 128 | [self updateBackgroundView]; 129 | [self _insertLeftViewControllerView]; 130 | [self _prepareViewForPanning]; 131 | [self _insertRightViewControllerViews]; 132 | } 133 | 134 | - (void)viewDidUnload { 135 | [super viewDidUnload]; 136 | _removeRectangleIndicatorView = nil; 137 | _draggingStartDate = nil; 138 | } 139 | 140 | #pragma mark - rotation 141 | 142 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 143 | // Return YES for supported orientations 144 | for (UIViewController *viewController in self.childViewControllers) { 145 | if (![viewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]) { 146 | return NO; 147 | } 148 | } 149 | return YES; 150 | } 151 | 152 | - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 153 | [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 154 | 155 | [self _willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 156 | } 157 | 158 | - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 159 | [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 160 | 161 | for (UIViewController *viewController in self.childViewControllers) { 162 | [viewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 163 | } 164 | } 165 | 166 | - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 167 | for (UIViewController *viewController in self.childViewControllers) { 168 | [viewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 169 | } 170 | } 171 | 172 | #pragma mark - private implementation 173 | 174 | - (void)updateBackgroundView { 175 | if (self.isViewLoaded) { 176 | _backgroundView.frame = self.view.bounds; 177 | _backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 178 | [self.view insertSubview:_backgroundView atIndex:0]; 179 | } 180 | } 181 | 182 | @end 183 | 184 | 185 | 186 | 187 | 188 | 189 | @implementation UIViewController (ANAdvancedNavigationController) 190 | 191 | - (ANAdvancedNavigationController *)advancedNavigationController { 192 | UIViewController *viewController = self.parentViewController; 193 | while (viewController != nil) { 194 | if ([viewController isKindOfClass:[ANAdvancedNavigationController class] ]) { 195 | return (ANAdvancedNavigationController *)viewController; 196 | } else { 197 | viewController = viewController.parentViewController; 198 | } 199 | } 200 | return nil; 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANRectangleView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANRectangleView.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ANRectangleView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANRectangleView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANRectangleView.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANRectangleView.h" 10 | #import 11 | 12 | @implementation ANRectangleView 13 | 14 | - (id)initWithFrame:(CGRect)frame { 15 | if (self = [super initWithFrame:frame]) { 16 | // Initialization code 17 | self.backgroundColor = [UIColor clearColor]; 18 | self.layer.needsDisplayOnBoundsChange = YES; 19 | } 20 | return self; 21 | } 22 | 23 | // Only override drawRect: if you perform custom drawing. 24 | // An empty implementation adversely affects performance during animation. 25 | - (void)drawRect:(CGRect)rect { 26 | // Drawing code 27 | static CGFloat inset = 5.0f; 28 | UIBezierPath *roundRectPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, inset, inset) cornerRadius:10.0f]; 29 | [[UIColor colorWithWhite:0.0f alpha:0.25f] setFill]; 30 | 31 | [roundRectPath fill]; 32 | [[UIColor whiteColor] setStroke]; 33 | 34 | [roundRectPath setLineWidth:1.5f]; 35 | [roundRectPath stroke]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANRemoveRectangleIndicatorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANRemoveRectangleIndicatorView.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANRectangleView.h" 11 | 12 | typedef enum { 13 | ANRemoveRectangleIndicatorViewStateHidden = 0, 14 | ANRemoveRectangleIndicatorViewStateVisible, 15 | ANRemoveRectangleIndicatorViewStateFlippedToRight, 16 | ANRemoveRectangleIndicatorViewStateRemovedRight 17 | } ANRemoveRectangleIndicatorViewState; 18 | 19 | 20 | 21 | 22 | 23 | @interface ANRemoveRectangleIndicatorView : UIView { 24 | ANRectangleView *_firstRectangleView; 25 | ANRectangleView *_secondRectangleView; 26 | 27 | ANRemoveRectangleIndicatorViewState _state; 28 | 29 | CGPoint _secondRectangleViewCenterPoint; 30 | CGPoint _secondRectangleViewFlippedCenterPoint; 31 | CGPoint _secondRectangleViewRemovedCenterPoint; 32 | } 33 | 34 | @property (nonatomic, retain, readonly) ANRectangleView *firstRectangleView; 35 | @property (nonatomic, retain, readonly) ANRectangleView *secondRectangleView; 36 | 37 | @property (nonatomic, assign) ANRemoveRectangleIndicatorViewState state; 38 | - (void)setState:(ANRemoveRectangleIndicatorViewState)state animated:(BOOL)animated; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/ANRemoveRectangleIndicatorView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANRemoveRectangleIndicatorView.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 29.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANRemoveRectangleIndicatorView.h" 10 | 11 | static CGFloat kANRemoveRectangleIndicatorViewAnimationDuration = 0.15f; 12 | 13 | @implementation ANRemoveRectangleIndicatorView 14 | @synthesize firstRectangleView=_firstRectangleView, secondRectangleView=_secondRectangleView, state=_state; 15 | 16 | - (void)setState:(ANRemoveRectangleIndicatorViewState)state { 17 | [self setState:state animated:NO]; 18 | } 19 | 20 | - (void)setState:(ANRemoveRectangleIndicatorViewState)state animated:(BOOL)animated { 21 | if (state != _state) { 22 | __block CGFloat animationDuration = kANRemoveRectangleIndicatorViewAnimationDuration; 23 | void(^animationBlock)(void) = ^(void) { 24 | switch (state) { 25 | case ANRemoveRectangleIndicatorViewStateHidden: 26 | self.alpha = 0.0f; 27 | _secondRectangleView.center = _secondRectangleViewCenterPoint; 28 | _secondRectangleView.transform = CGAffineTransformIdentity; 29 | _secondRectangleView.alpha = 1.0f; 30 | break; 31 | case ANRemoveRectangleIndicatorViewStateVisible: 32 | self.alpha = 1.0f; 33 | _secondRectangleView.center = _secondRectangleViewCenterPoint; 34 | _secondRectangleView.transform = CGAffineTransformIdentity; 35 | _secondRectangleView.alpha = 1.0f; 36 | break; 37 | case ANRemoveRectangleIndicatorViewStateFlippedToRight: 38 | self.alpha = 1.0f; 39 | _secondRectangleView.center = _secondRectangleViewFlippedCenterPoint; 40 | _secondRectangleView.transform = CGAffineTransformMakeRotation(M_PI / 8.0f); 41 | _secondRectangleView.alpha = 0.5f; 42 | break; 43 | case ANRemoveRectangleIndicatorViewStateRemovedRight: 44 | self.alpha = 1.0f; 45 | _secondRectangleView.center = _secondRectangleViewRemovedCenterPoint; 46 | _secondRectangleView.transform = CGAffineTransformMakeRotation(M_PI / 2.0f); 47 | _secondRectangleView.alpha = 0.5f; 48 | break; 49 | default: 50 | break; 51 | } 52 | }; 53 | 54 | _state = state; 55 | if (animated) { 56 | [UIView animateWithDuration:animationDuration 57 | animations:animationBlock]; 58 | } else { 59 | animationBlock(); 60 | } 61 | } 62 | } 63 | 64 | - (id)initWithFrame:(CGRect)frame { 65 | if (self = [super initWithFrame:frame]) { 66 | // Initialization code 67 | static CGFloat topOffset = 20.0f; 68 | CGFloat width = CGRectGetWidth(self.bounds)/2.5f; 69 | self.backgroundColor = [UIColor clearColor]; 70 | _firstRectangleView = [[ANRectangleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, width, CGRectGetHeight(self.bounds)-topOffset)]; 71 | [self addSubview:_firstRectangleView]; 72 | 73 | _secondRectangleView = [[ANRectangleView alloc] initWithFrame:CGRectMake(width/2.0f, topOffset, width, CGRectGetHeight(self.bounds)-20.0f)]; 74 | _secondRectangleViewCenterPoint = _secondRectangleView.center; 75 | _secondRectangleViewFlippedCenterPoint = CGPointMake(_secondRectangleViewCenterPoint.x + 80.0f, _secondRectangleViewCenterPoint.y + 30.0f); 76 | _secondRectangleViewRemovedCenterPoint = CGPointMake(_secondRectangleViewFlippedCenterPoint.x + 10.0f, _secondRectangleViewFlippedCenterPoint.y + 150.0f); 77 | [self addSubview:_secondRectangleView]; 78 | 79 | self.state = ANRemoveRectangleIndicatorViewStateHidden; 80 | self.alpha = 0.0f; 81 | } 82 | return self; 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/ANAdvancedNavigationController+private.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+private.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController.h" 10 | #import 11 | #import "ANRemoveRectangleIndicatorView.h" 12 | 13 | extern const CGFloat ANAdvancedNavigationControllerDefaultAnimationDuration; 14 | extern const CGFloat ANAdvancedNavigationControllerDefaultDraggingDistance; 15 | 16 | @interface ANAdvancedNavigationController () { 17 | UIViewController *_leftViewController; 18 | UIView *_backgroundView; 19 | 20 | NSMutableArray *_viewControllers; 21 | 22 | CGFloat _draggingDistance; 23 | NSDate *_draggingStartDate; 24 | NSInteger _draggingRightAnchorViewControllerIndex; 25 | 26 | ANRemoveRectangleIndicatorView *_removeRectangleIndicatorView; 27 | 28 | id __weak _delegate; 29 | 30 | NSUInteger _indexOfFrontViewController; 31 | } 32 | 33 | - (void)updateBackgroundView; 34 | 35 | @property (nonatomic, retain) NSDate *draggingStartDate; 36 | 37 | @property (nonatomic, retain) NSMutableArray *viewControllers; 38 | 39 | @property (nonatomic, retain) ANRemoveRectangleIndicatorView *removeRectangleIndicatorView; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/LeftViewController/ANAdvancedNavigationController+LeftViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+LeftViewController.h 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewController) 13 | 14 | - (void)_setLeftViewController:(UIViewController *)leftViewController; 15 | - (void)_insertLeftViewControllerView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/LeftViewController/ANAdvancedNavigationController+LeftViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+LeftViewController.m 3 | // ANAdvancedNavigationController 4 | // 5 | // Created by Oliver Letterer on 28.06.11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController+LeftViewController.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewControllerPrivate) 13 | - (void)__removeLeftViewControllerView; 14 | - (void)__removeLeftViewController; 15 | @end 16 | 17 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewControllerPrivate) 18 | 19 | - (void)__removeLeftViewControllerView { 20 | if (self.isViewLoaded) { 21 | [_leftViewController viewWillDisappear:NO]; 22 | [_leftViewController.view removeFromSuperview]; 23 | [_leftViewController viewDidDisappear:NO]; 24 | } 25 | } 26 | 27 | - (void)__removeLeftViewController { 28 | [_leftViewController willMoveToParentViewController:nil]; 29 | if (self.isViewLoaded) { 30 | [self __removeLeftViewControllerView]; 31 | } 32 | [_leftViewController removeFromParentViewController]; 33 | _leftViewController = nil; 34 | } 35 | 36 | @end 37 | 38 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_LeftViewController) 39 | 40 | - (void)_setLeftViewController:(UIViewController *)leftViewController { 41 | [self __removeLeftViewController]; 42 | 43 | if (leftViewController != nil) { 44 | _leftViewController = leftViewController; 45 | [self addChildViewController:leftViewController]; 46 | if (self.isViewLoaded) { 47 | [self _insertLeftViewControllerView]; 48 | } 49 | [_leftViewController didMoveToParentViewController:self]; 50 | } 51 | } 52 | 53 | - (void)_insertLeftViewControllerView { 54 | if (self.isViewLoaded) { 55 | _leftViewController.view.frame = CGRectMake(0.0f, 0.0f, ANAdvancedNavigationControllerDefaultLeftViewControllerWidth, CGRectGetHeight(self.view.bounds)); 56 | _leftViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight; 57 | [_leftViewController viewWillAppear:NO]; 58 | [self.view addSubview:_leftViewController.view]; 59 | [_leftViewController viewDidAppear:NO]; 60 | } 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers+Anchors.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers+Anchors.h 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Anchors) 13 | 14 | @property (nonatomic, readonly) CGFloat __minimumDragOffsetToShowRemoveInformation; 15 | 16 | // anchor points, at which the viewControllers views center will be layed out 17 | @property (nonatomic, readonly) CGFloat __anchorPortraitLeft; 18 | @property (nonatomic, readonly) CGFloat __anchorPortraitRight; 19 | @property (nonatomic, readonly) CGFloat __anchorLandscapeLeft; 20 | @property (nonatomic, readonly) CGFloat __anchorLandscapeMiddle; 21 | @property (nonatomic, readonly) CGFloat __anchorLandscapeRight; 22 | @property (nonatomic, readonly) CGFloat __leftAnchorForInterfaceOrientation; 23 | @property (nonatomic, readonly) CGFloat __rightAnchorForInterfaceOrientation; 24 | - (CGFloat)__leftAnchorForInterfaceOrientationAndRightViewController:(UIViewController *)rightViewController; 25 | 26 | - (CGPoint)__centerPointForRightViewController:(UIViewController *)rightViewController withIndexOfCurrentViewControllerAtRightAnchor:(NSUInteger)indexOfMostRightViewController; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers+Anchors.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers+Anchors.m 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController+RightViewControllers+Anchors.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | 12 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Anchors) 13 | 14 | - (CGFloat)__minimumDragOffsetToShowRemoveInformation { 15 | CGRect frame = self.removeRectangleIndicatorView.frame; 16 | return CGRectGetWidth(frame) + frame.origin.x + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f - 20.0f; 17 | } 18 | 19 | - (CGFloat)__leftBoundsPanningAnchor { 20 | // if we only have one viewController, we can pan infinite 21 | if (self.viewControllers.count <= 1) { 22 | return -CGFLOAT_MAX; 23 | } 24 | return ANAdvancedNavigationControllerDefaultLeftPanningOffset + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 25 | } 26 | 27 | - (CGFloat)__anchorPortraitLeft { 28 | return ANAdvancedNavigationControllerDefaultLeftPanningOffset + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 29 | } 30 | 31 | - (CGFloat)__anchorPortraitRight { 32 | return CGRectGetWidth(self.view.bounds) - ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 33 | } 34 | 35 | - (CGFloat)__anchorLandscapeLeft { 36 | return ANAdvancedNavigationControllerDefaultLeftPanningOffset + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 37 | } 38 | 39 | - (CGFloat)__anchorLandscapeMiddle { 40 | return ANAdvancedNavigationControllerDefaultLeftViewControllerWidth + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 41 | } 42 | 43 | - (CGFloat)__anchorLandscapeRight { 44 | return CGRectGetWidth(self.view.bounds) - ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f; 45 | } 46 | 47 | - (CGFloat)__leftAnchorForInterfaceOrientation { 48 | if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 49 | return self.__anchorPortraitLeft; 50 | } else { 51 | return self.__anchorLandscapeLeft; 52 | } 53 | } 54 | 55 | - (CGFloat)__rightAnchorForInterfaceOrientation { 56 | if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 57 | return self.__anchorPortraitRight; 58 | } else { 59 | return self.__anchorLandscapeRight; 60 | } 61 | } 62 | 63 | - (CGFloat)__leftAnchorForInterfaceOrientationAndRightViewController:(UIViewController *)rightViewController { 64 | CGFloat anchor = self.__leftAnchorForInterfaceOrientation; 65 | NSUInteger index = [self.viewControllers indexOfObject:rightViewController]; 66 | return anchor + index*2; 67 | } 68 | 69 | - (CGPoint)__centerPointForRightViewController:(UIViewController *)rightViewController 70 | withIndexOfCurrentViewControllerAtRightAnchor:(NSUInteger)indexOfMostRightViewController { 71 | 72 | if (![self.viewControllers containsObject:rightViewController]) { 73 | [NSException raise:NSInternalInconsistencyException format:@"rightViewController (%@) is not part of the viewController hierarchy", rightViewController]; 74 | } 75 | if (indexOfMostRightViewController >= self.viewControllers.count) { 76 | [NSException raise:NSInternalInconsistencyException format:@"indexOfMostRightViewController (%d) excedes number of ViewControllers (%d)", indexOfMostRightViewController, self.viewControllers.count]; 77 | } 78 | 79 | if (self.viewControllers.count <= 1) { // only one view controller 80 | CGFloat anchorPoint = 0.0; 81 | // move it to the right or to the middle based on interfaceOrientation 82 | if (UIDeviceOrientationIsPortrait(self.interfaceOrientation)) { 83 | anchorPoint = self.__anchorPortraitRight; 84 | } else { 85 | anchorPoint = self.__anchorLandscapeMiddle; 86 | } 87 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 88 | } 89 | 90 | // now we definetly have more that one viewController in our hierarchy 91 | NSUInteger indexOfRightViewController = [self.viewControllers indexOfObject:rightViewController]; 92 | 93 | if (indexOfRightViewController < indexOfMostRightViewController) { 94 | // the viewController needs to be put on our left stack 95 | return CGPointMake([self __leftAnchorForInterfaceOrientationAndRightViewController:rightViewController], CGRectGetHeight(self.view.bounds)/2.0f); 96 | } else if (indexOfRightViewController == indexOfMostRightViewController) { 97 | // this viewController must be pushed on our right site 98 | if (indexOfRightViewController == 0) { 99 | // its the first most down viewController 100 | CGFloat anchorPoint = 0.0f; 101 | // portrait -> move to left, landscape -> move to middle 102 | if (UIDeviceOrientationIsPortrait(self.interfaceOrientation)) { 103 | anchorPoint = self.__anchorPortraitRight; 104 | } else { 105 | anchorPoint = self.__anchorLandscapeMiddle; 106 | } 107 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 108 | } else { 109 | return CGPointMake(self.__rightAnchorForInterfaceOrientation, CGRectGetHeight(self.view.bounds)/2.0f); 110 | } 111 | } else { 112 | if (UIDeviceOrientationIsLandscape(self.interfaceOrientation) && indexOfMostRightViewController == 0) { 113 | // our most right one will be in the middle 114 | CGFloat anchorPoint = self.__anchorLandscapeMiddle + (CGFloat)(indexOfRightViewController - indexOfMostRightViewController) * ANAdvancedNavigationControllerDefaultDraggingDistance; 115 | 116 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 117 | } 118 | // this viewController is on the right site of our current active viewController 119 | CGFloat anchorPoint = self.__rightAnchorForInterfaceOrientation + (CGFloat)(indexOfRightViewController - indexOfMostRightViewController) * ANAdvancedNavigationControllerDefaultDraggingDistance; 120 | 121 | return CGPointMake(anchorPoint, CGRectGetHeight(self.view.bounds)/2.0f); 122 | } 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers.h 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers) 13 | 14 | - (void)_pushViewController:(UIViewController *)viewController 15 | afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 16 | 17 | - (void)_popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated; 18 | 19 | - (void)_prepareViewForPanning; 20 | 21 | - (void)_willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; 22 | 23 | - (void)_insertRightViewControllerInDataModel:(UIViewController *)rightViewController; 24 | - (void)_insertRightViewControllerViews; 25 | 26 | - (void)_setIndexOfFrontViewController:(NSUInteger)indexOfFrontViewController; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /SampleApplication/ANAdvancedNavigationController/Private/RightViewControllers/ANAdvancedNavigationController+RightViewControllers.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANAdvancedNavigationController+RightViewControllers.m 3 | // iGithub 4 | // 5 | // Created by Oliver Letterer on 14.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "ANAdvancedNavigationController+RightViewControllers.h" 10 | #import "ANAdvancedNavigationController+private.h" 11 | #import "ANAdvancedNavigationController+RightViewControllers+Anchors.h" 12 | #import 13 | 14 | @interface ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Private) 15 | 16 | // inserting new viewControllers 17 | - (void)__pushRootViewController:(UIViewController *)rootViewController animated:(BOOL)animated; 18 | - (void)__pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated; 19 | 20 | // removing old viewControllers 21 | - (void)__removeRightViewController:(UIViewController *)rightViewController animated:(BOOL)animated; 22 | 23 | // concistency stuff 24 | - (void)__numberOfRightViewControllersDidChanged; 25 | - (void)__updateViewControllerShadows; 26 | 27 | // managing rightViewControllers views 28 | - (UIView *)__loadViewForNewRightViewController:(UIViewController *)rightViewController; 29 | - (UIView *)__viewForRightViewController:(UIViewController *)rightViewController; 30 | - (BOOL)__isRightViewControllerAlreayInViewHierarchy:(UIViewController *)rightViewController; 31 | - (void)__moveRightViewControllerToRightAnchorPoint:(UIViewController *)rightViewController animated:(BOOL)animated; 32 | 33 | // panning 34 | - (UIViewController *)__bestRightAnchorPointViewControllerWithIndex:(NSInteger *)index; 35 | - (void)__updateViewControllersWithTranslation:(CGFloat)translation; 36 | - (void)__mainPanGestureRecognizedDidRecognizePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer; 37 | 38 | - (void)__popViewControllersAfterDraggingFarToTheRight; 39 | 40 | @end 41 | 42 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers_Private) 43 | 44 | #pragma mark - inserting new viewControllers 45 | 46 | - (void)__pushRootViewController:(UIViewController *)rootViewController animated:(BOOL)animated { 47 | NSArray *oldViewControllers = [self.viewControllers copy]; 48 | 49 | [oldViewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 50 | [self __removeRightViewController:obj animated:animated]; 51 | }]; 52 | 53 | [self.viewControllers addObject:rootViewController]; 54 | [self addChildViewController:rootViewController]; 55 | [self __numberOfRightViewControllersDidChanged]; 56 | 57 | // now display the new rootViewController, if the view is loaded 58 | UIView *newView = [self __loadViewForNewRightViewController:rootViewController]; 59 | 60 | [rootViewController viewWillAppear:animated]; 61 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPushViewController:afterViewController:animated:)]) { 62 | [self.delegate advancedNavigationController:self willPushViewController:rootViewController afterViewController:nil animated:animated]; 63 | } 64 | if (newView) { 65 | newView.center = CGPointMake(CGRectGetWidth(self.view.bounds) + ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f, CGRectGetHeight(self.view.bounds)/2.0f); 66 | [self.view addSubview:newView]; 67 | CGPoint nextCenterPoint = [self __centerPointForRightViewController:rootViewController withIndexOfCurrentViewControllerAtRightAnchor:0]; 68 | if (animated) { 69 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 70 | animations:^(void) { 71 | newView.center = nextCenterPoint; 72 | } 73 | completion:^(BOOL finished) { 74 | [rootViewController viewDidAppear:animated]; 75 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:afterViewController:animated:)]) { 76 | [self.delegate advancedNavigationController:self didPushViewController:rootViewController afterViewController:nil animated:animated]; 77 | } 78 | [rootViewController didMoveToParentViewController:self]; 79 | _indexOfFrontViewController = 0; 80 | }]; 81 | } else { 82 | newView.center = nextCenterPoint; 83 | [rootViewController viewDidAppear:animated]; 84 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:afterViewController:animated:)]) { 85 | [self.delegate advancedNavigationController:self didPushViewController:rootViewController afterViewController:nil animated:animated]; 86 | } 87 | [rootViewController didMoveToParentViewController:self]; 88 | _indexOfFrontViewController = 0; 89 | } 90 | } 91 | } 92 | 93 | - (void)__pushViewController:(UIViewController *)viewController afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated { 94 | if ([self.viewControllers containsObject:viewController]) { 95 | NSLog(@"viewController (%@) is already part of the viewController Hierarchy", viewController); 96 | return; 97 | } 98 | if (![self.viewControllers containsObject:afterViewController]) { 99 | NSLog(@"afterViewController (%@) is not part of the viewController Hierarchy", afterViewController); 100 | } 101 | 102 | NSUInteger afterIndex = [self.viewControllers indexOfObject:afterViewController]+1; 103 | NSIndexSet *deleteIndexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(afterIndex, self.viewControllers.count - afterIndex)]; 104 | 105 | NSArray *oldViewControllers = [self.viewControllers objectsAtIndexes:deleteIndexSet]; 106 | 107 | // remove all viewControllers, that come after afterViewController 108 | [oldViewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 109 | [self __removeRightViewController:obj animated:animated]; 110 | }]; 111 | 112 | // insert viewController in data structure 113 | [self.viewControllers addObject:viewController]; 114 | [self addChildViewController:viewController]; 115 | [self __numberOfRightViewControllersDidChanged]; 116 | 117 | UIView *newView = [self __loadViewForNewRightViewController:viewController]; 118 | 119 | [viewController viewWillAppear:animated]; 120 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPushViewController:afterViewController:animated:)]) { 121 | [self.delegate advancedNavigationController:self willPushViewController:viewController afterViewController:afterViewController animated:animated]; 122 | } 123 | if (newView) { 124 | [self.view addSubview:newView]; 125 | newView.center = CGPointMake(CGRectGetWidth(self.view.bounds)+ANAdvancedNavigationControllerDefaultViewControllerWidth/2.0f, CGRectGetHeight(self.view.bounds)/2.0f); 126 | // now insert the new view into our view hirarchy 127 | if (animated) { 128 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 129 | animations:^(void) { 130 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 131 | UIView *view = [self __viewForRightViewController:obj]; 132 | view.center = [self __centerPointForRightViewController:obj 133 | withIndexOfCurrentViewControllerAtRightAnchor:self.viewControllers.count-1]; 134 | }]; 135 | } 136 | completion:^(BOOL finished) { 137 | [viewController viewDidAppear:animated]; 138 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:afterViewController:animated:)]) { 139 | [self.delegate advancedNavigationController:self didPushViewController:viewController afterViewController:afterViewController animated:animated]; 140 | } 141 | [viewController didMoveToParentViewController:self]; 142 | _indexOfFrontViewController = self.viewControllers.count-1; 143 | }]; 144 | } else { 145 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 146 | UIView *view = [self __viewForRightViewController:obj]; 147 | view.center = [self __centerPointForRightViewController:obj 148 | withIndexOfCurrentViewControllerAtRightAnchor:self.viewControllers.count-1]; 149 | }]; 150 | [viewController viewDidAppear:animated]; 151 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPushViewController:animated:)]) { 152 | [self.delegate advancedNavigationController:self didPushViewController:viewController afterViewController:afterViewController animated:animated]; 153 | } 154 | [viewController didMoveToParentViewController:self]; 155 | _indexOfFrontViewController = self.viewControllers.count-1; 156 | } 157 | } 158 | } 159 | 160 | #pragma mark - removing old viewControllers 161 | 162 | - (void)__removeRightViewController:(UIViewController *)rightViewController animated:(BOOL)animated { 163 | if (![self.viewControllers containsObject:rightViewController]) { 164 | NSLog(@"rightViewController (%@) is not part of the viewController Hierarchy", rightViewController); 165 | return; 166 | } 167 | 168 | [rightViewController willMoveToParentViewController:nil]; 169 | 170 | [self.viewControllers removeObject:rightViewController]; 171 | [self __numberOfRightViewControllersDidChanged]; 172 | 173 | [rightViewController viewWillDisappear:animated]; 174 | UIView *view = [self __viewForRightViewController:rightViewController]; 175 | if (animated) { 176 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 177 | animations:^(void) { 178 | CGPoint center = view.center; 179 | center.x = CGRectGetWidth(self.view.bounds) + ANAdvancedNavigationControllerDefaultLeftViewControllerWidth; 180 | view.center = center; 181 | } 182 | completion:^(BOOL finished) { 183 | [view removeFromSuperview]; 184 | [rightViewController viewDidDisappear:animated]; 185 | [rightViewController removeFromParentViewController]; 186 | _indexOfFrontViewController = self.viewControllers.count-1; 187 | }]; 188 | } else { 189 | [view removeFromSuperview]; 190 | [rightViewController viewDidDisappear:animated]; 191 | [rightViewController removeFromParentViewController]; 192 | _indexOfFrontViewController = self.viewControllers.count-1; 193 | } 194 | } 195 | 196 | - (void)__popViewControllersAfterDraggingFarToTheRight { 197 | NSArray *oldArray = [self.viewControllers copy]; 198 | 199 | [oldArray enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 200 | if (idx > 0) { 201 | [self __removeRightViewController:obj animated:NO]; 202 | } 203 | }]; 204 | 205 | UIViewController *viewController = [self.viewControllers objectAtIndex:0]; 206 | 207 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPopToViewController:animated:)]) { 208 | [self.delegate advancedNavigationController:self willPopToViewController:viewController animated:YES]; 209 | } 210 | self.removeRectangleIndicatorView.state = ANRemoveRectangleIndicatorViewStateFlippedToRight; 211 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 212 | animations:^(void) { 213 | self.removeRectangleIndicatorView.state = ANRemoveRectangleIndicatorViewStateRemovedRight; 214 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:NO]; 215 | } 216 | completion:^(BOOL finished) { 217 | [self __numberOfRightViewControllersDidChanged]; 218 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPopToViewController:animated:)]) { 219 | [self.delegate advancedNavigationController:self didPopToViewController:viewController animated:YES]; 220 | } 221 | _indexOfFrontViewController = 0; 222 | }]; 223 | } 224 | 225 | #pragma mark - concistency stuff 226 | 227 | - (void)__numberOfRightViewControllersDidChanged { 228 | if (self.viewControllers.count <= 1) { 229 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateHidden animated:YES]; 230 | } else { 231 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateVisible animated:YES]; 232 | } 233 | } 234 | 235 | - (void)__updateViewControllerShadows { 236 | [self.viewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 237 | UIView *view = [self __viewForRightViewController:obj]; 238 | CALayer *layer = view.layer; 239 | layer.shadowPath = [UIBezierPath bezierPathWithRect:view.bounds].CGPath; 240 | }]; 241 | } 242 | 243 | #pragma mark - rightViewControllers views 244 | 245 | - (UIView *)__loadViewForNewRightViewController:(UIViewController *)rightViewController { 246 | if (!self.isViewLoaded) { 247 | return nil; 248 | } 249 | if (rightViewController.isViewLoaded) { 250 | if (rightViewController.view.superview) { 251 | return rightViewController.view.superview; 252 | } 253 | } 254 | UIView *wrapperView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, ANAdvancedNavigationControllerDefaultViewControllerWidth, CGRectGetHeight(self.view.bounds))]; 255 | wrapperView.backgroundColor = [UIColor blackColor]; 256 | 257 | rightViewController.view.frame = wrapperView.bounds; 258 | [wrapperView addSubview:rightViewController.view]; 259 | rightViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight; 260 | wrapperView.autoresizingMask = rightViewController.view.autoresizingMask; 261 | 262 | CALayer *layer = wrapperView.layer; 263 | layer.masksToBounds = NO; 264 | layer.shadowPath = [UIBezierPath bezierPathWithRect:rightViewController.view.bounds].CGPath; 265 | layer.shadowColor = [UIColor blackColor].CGColor; 266 | layer.shadowRadius = 15.0f; 267 | layer.shadowOpacity = 0.5f; 268 | layer.shadowOffset = CGSizeMake(0.0f, 0.0f); 269 | 270 | return wrapperView; 271 | } 272 | 273 | - (UIView *)__viewForRightViewController:(UIViewController *)rightViewController { 274 | if (!rightViewController.isViewLoaded) { 275 | return nil; 276 | } 277 | return rightViewController.view.superview; 278 | } 279 | 280 | - (BOOL)__isRightViewControllerAlreayInViewHierarchy:(UIViewController *)rightViewController { 281 | return [self __viewForRightViewController:rightViewController].superview == self.view; 282 | } 283 | 284 | - (void)__moveRightViewControllerToRightAnchorPoint:(UIViewController *)rightViewController animated:(BOOL)animated { 285 | NSUInteger rightViewControllerIndex = [self.viewControllers indexOfObject:rightViewController]; 286 | _indexOfFrontViewController = rightViewControllerIndex; 287 | _draggingRightAnchorViewControllerIndex = rightViewControllerIndex; 288 | 289 | if (animated) { 290 | UIView *rightViewControllerView = [self __viewForRightViewController:rightViewController]; 291 | CGPoint currentRightCenterPoint = rightViewControllerView.center; 292 | CGPoint finalRightCenterPoint = [self __centerPointForRightViewController:rightViewController withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 293 | 294 | CGFloat distance = (finalRightCenterPoint.x - currentRightCenterPoint.x)*0.05f; 295 | 296 | if (self.viewControllers.count == 1) { 297 | // well, we got only one viewController, just set this one to the center with a simple UIView-animation 298 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 299 | animations:^(void) { 300 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 301 | UIView *view = [self __viewForRightViewController:obj]; 302 | view.center = [self __centerPointForRightViewController:obj withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 303 | }]; 304 | }]; 305 | } else { 306 | // now we got more that one viewController, we need a little bounde animation 307 | 308 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 309 | UIView *view = [self __viewForRightViewController:obj]; 310 | CGPoint finalCenterPoint = [self __centerPointForRightViewController:obj withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 311 | 312 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"]; 313 | animation.calculationMode = kCAAnimationLinear; 314 | 315 | if (abs(idx - rightViewControllerIndex) <= 1 && finalCenterPoint.x+distance >= self.__leftAnchorForInterfaceOrientation) { 316 | animation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:view.center.x], 317 | [NSNumber numberWithFloat:finalCenterPoint.x], 318 | [NSNumber numberWithFloat:finalCenterPoint.x+distance], 319 | [NSNumber numberWithFloat:finalCenterPoint.x], 320 | nil]; 321 | } else { 322 | animation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:view.center.x], 323 | [NSNumber numberWithFloat:finalCenterPoint.x], 324 | [NSNumber numberWithFloat:finalCenterPoint.x], 325 | [NSNumber numberWithFloat:finalCenterPoint.x], 326 | nil]; 327 | } 328 | 329 | animation.duration = 0.5f; 330 | 331 | [view.layer addAnimation:animation forKey:nil]; 332 | view.layer.position = finalCenterPoint; 333 | }]; 334 | } 335 | } else { 336 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 337 | UIView *view = [self __viewForRightViewController:obj]; 338 | view.center = [self __centerPointForRightViewController:obj withIndexOfCurrentViewControllerAtRightAnchor:rightViewControllerIndex]; 339 | }]; 340 | } 341 | } 342 | 343 | #pragma mark - Panning 344 | 345 | - (UIViewController *)__bestRightAnchorPointViewControllerWithIndex:(NSInteger *)index { 346 | 347 | __block NSUInteger bestIndex = 0; 348 | __block CGFloat bestDistance = CGFLOAT_MAX; 349 | 350 | [self.viewControllers enumerateObjectsUsingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 351 | UIViewController *viewController = obj; 352 | UIView *view = [self __viewForRightViewController:viewController]; 353 | 354 | CGFloat distance = fabsf(view.center.x - self.__rightAnchorForInterfaceOrientation); 355 | if (distance <= bestDistance) { 356 | bestDistance = distance; 357 | bestIndex = idx; 358 | } 359 | }]; 360 | 361 | if (index) { 362 | *index = bestIndex; 363 | } 364 | 365 | if (bestIndex == NSNotFound) { 366 | return nil; 367 | } 368 | 369 | return [self.viewControllers objectAtIndex:bestIndex]; 370 | } 371 | 372 | - (void)__updateViewControllersWithTranslation:(CGFloat)translation { 373 | NSUInteger count = self.viewControllers.count; 374 | 375 | CGFloat minDragOffsetToShowRemoveInformation = self.__minimumDragOffsetToShowRemoveInformation; 376 | __block UIViewController *previousViewController = nil; 377 | [self.viewControllers enumerateObjectsWithOptions:NSEnumerationReverse 378 | usingBlock:^(__strong id obj, NSUInteger idx, BOOL *stop) { 379 | UIViewController *currentViewController = obj; 380 | UIView *view = [self __viewForRightViewController:currentViewController]; 381 | 382 | CGPoint currentCenter = view.center; 383 | CGFloat leftBounds = [self __leftAnchorForInterfaceOrientationAndRightViewController:currentViewController]; 384 | 385 | if (currentCenter.x + translation < leftBounds) { 386 | currentCenter.x = leftBounds; 387 | } else { 388 | if ([self __viewForRightViewController:previousViewController].center.x - currentCenter.x >= ANAdvancedNavigationControllerDefaultDraggingDistance || !previousViewController || translation < 0.0f) { 389 | currentCenter.x += translation; 390 | } 391 | } 392 | 393 | view.center = currentCenter; 394 | 395 | previousViewController = currentViewController; 396 | 397 | if (count > 1 && idx == 0) { 398 | // first viewController has moved enough to the right 399 | if (currentCenter.x > minDragOffsetToShowRemoveInformation) { 400 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateFlippedToRight animated:YES]; 401 | } else { 402 | [self.removeRectangleIndicatorView setState:ANRemoveRectangleIndicatorViewStateVisible animated:YES]; 403 | } 404 | } 405 | }]; 406 | } 407 | 408 | - (void)__mainPanGestureRecognizedDidRecognizePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { 409 | if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { 410 | _draggingDistance = 0.0f; 411 | self.draggingStartDate = [NSDate date]; 412 | } else if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { 413 | // changed 414 | CGFloat translation = [panGestureRecognizer translationInView:self.view].x; 415 | [panGestureRecognizer setTranslation:CGPointZero inView:self.view]; 416 | 417 | if (self.viewControllers.count == 1) { 418 | translation /= 2.0f; 419 | } 420 | 421 | _draggingDistance += translation; 422 | 423 | [self __updateViewControllersWithTranslation:translation]; 424 | } else if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { 425 | // check, if we need to pop every viewController except the first one 426 | BOOL didPopViewControllers = NO; 427 | if (self.viewControllers.count > 1) { 428 | UIViewController *firstViewController = [self.viewControllers objectAtIndex:0]; 429 | UIView *view = [self __viewForRightViewController:firstViewController]; 430 | if (view.center.x > self.__minimumDragOffsetToShowRemoveInformation) { 431 | didPopViewControllers = YES; 432 | [self __popViewControllersAfterDraggingFarToTheRight]; 433 | } 434 | } 435 | 436 | if (self.viewControllers.count > 0 && !didPopViewControllers) { 437 | NSDate *now = [NSDate date]; 438 | CGFloat draggingTimeInterval = [now timeIntervalSinceDate:self.draggingStartDate]; 439 | // find that view controller, that is the best for the right anchor position 440 | NSInteger index = 0; 441 | UIViewController *viewController = [self __bestRightAnchorPointViewControllerWithIndex:&index]; 442 | if (viewController) { 443 | if (_draggingRightAnchorViewControllerIndex == index && draggingTimeInterval < 0.5f) { 444 | // we did "swipe", just move the next viewController in that direction in 445 | if (_draggingDistance > 0.0f) { 446 | index--; 447 | } else { 448 | index++; 449 | } 450 | 451 | if (index < 0) { 452 | index = 0; 453 | } else if (index >= self.viewControllers.count) { 454 | index = self.viewControllers.count-1; 455 | } 456 | viewController = [self.viewControllers objectAtIndex:index]; 457 | } 458 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:YES]; 459 | } 460 | } 461 | 462 | _draggingDistance = 0.0f; 463 | self.draggingStartDate = nil; 464 | } 465 | } 466 | 467 | @end 468 | 469 | 470 | 471 | 472 | 473 | 474 | @implementation ANAdvancedNavigationController (ANAdvancedNavigationController_RightViewControllers) 475 | 476 | #pragma setters and getters 477 | 478 | - (void)_setIndexOfFrontViewController:(NSUInteger)indexOfFrontViewController { 479 | if (!(indexOfFrontViewController < self.viewControllers.count)) { 480 | NSLog(@"indexOfFrontViewController (%d) exceeds viewControllers bounds (%d)", indexOfFrontViewController, self.viewControllers.count); 481 | return; 482 | } 483 | 484 | if (indexOfFrontViewController != _indexOfFrontViewController) { 485 | _indexOfFrontViewController = indexOfFrontViewController; 486 | 487 | if (self.isViewLoaded) { 488 | [self __moveRightViewControllerToRightAnchorPoint:[self.viewControllers objectAtIndex:_indexOfFrontViewController] animated:NO]; 489 | } 490 | } 491 | } 492 | 493 | #pragma mark - Pushing and poping 494 | 495 | - (void)_pushViewController:(UIViewController *)viewController 496 | afterViewController:(UIViewController *)afterViewController animated:(BOOL)animated { 497 | // first lets do some concistency checks 498 | if ([self.viewControllers containsObject:viewController] || _leftViewController == viewController) { 499 | // viewController cant be part of the current viewController hierarchy 500 | NSLog(@"viewController (%@) is already part of the viewController Hierarchy", viewController); 501 | return; 502 | } 503 | if (![self.viewControllers containsObject:afterViewController] && afterViewController != nil) { 504 | NSLog(@"afterViewController (%@) is not part of the viewController Hierarchy", afterViewController); 505 | return; 506 | } 507 | 508 | if (afterViewController == _leftViewController) { 509 | afterViewController = nil; 510 | } 511 | 512 | if (afterViewController == nil) { 513 | // we need to push a new rootViewController 514 | [self __pushRootViewController:viewController animated:animated]; 515 | } else { 516 | [self __pushViewController:viewController afterViewController:afterViewController animated:animated]; 517 | } 518 | 519 | _draggingRightAnchorViewControllerIndex = [self.viewControllers indexOfObject:viewController]; 520 | } 521 | 522 | - (void)_popViewControllersToViewController:(UIViewController *)viewController animated:(BOOL)animated { 523 | if (![self.viewControllers containsObject:viewController]) { 524 | NSLog(@"viewController (%@) is not part of the viewController Hierarchy", viewController); 525 | return; 526 | } 527 | 528 | NSArray *oldArray = [self.viewControllers copy]; 529 | 530 | NSInteger index = [self.viewControllers indexOfObject:viewController]+1; 531 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:willPopToViewController:animated:)]) { 532 | [self.delegate advancedNavigationController:self willPopToViewController:viewController animated:animated]; 533 | } 534 | if (animated) { 535 | [UIView animateWithDuration:ANAdvancedNavigationControllerDefaultAnimationDuration 536 | animations:^(void) { 537 | [oldArray enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, self.viewControllers.count-index)] 538 | options:NSEnumerationConcurrent 539 | usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 540 | [self __removeRightViewController:obj animated:NO]; 541 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:NO]; 542 | }]; 543 | } 544 | completion:^(BOOL finished) { 545 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPopToViewController:animated:)]) { 546 | [self.delegate advancedNavigationController:self didPopToViewController:viewController animated:animated]; 547 | } 548 | }]; 549 | } else { 550 | [oldArray enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, self.viewControllers.count-index)] 551 | options:NSEnumerationConcurrent 552 | usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 553 | [self __removeRightViewController:obj animated:NO]; 554 | }]; 555 | [self __moveRightViewControllerToRightAnchorPoint:viewController animated:NO]; 556 | if ([self.delegate respondsToSelector:@selector(advancedNavigationController:didPopToViewController:animated:)]) { 557 | [self.delegate advancedNavigationController:self didPopToViewController:viewController animated:animated]; 558 | } 559 | } 560 | } 561 | 562 | - (void)_prepareViewForPanning { 563 | UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(__mainPanGestureRecognizedDidRecognizePanGesture:)]; 564 | recognizer.maximumNumberOfTouches = 1; 565 | [self.view addGestureRecognizer:recognizer]; 566 | } 567 | 568 | - (void)_willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 569 | for (UIViewController *viewController in self.childViewControllers) { 570 | [viewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 571 | } 572 | [self __updateViewControllerShadows]; 573 | 574 | if (self.viewControllers.count > _draggingRightAnchorViewControllerIndex) { 575 | [self __moveRightViewControllerToRightAnchorPoint:[self.viewControllers objectAtIndex:_draggingRightAnchorViewControllerIndex] animated:NO]; 576 | } 577 | } 578 | 579 | - (void)_insertRightViewControllerInDataModel:(UIViewController *)rightViewController { 580 | [self.viewControllers addObject:rightViewController]; 581 | [self addChildViewController:rightViewController]; 582 | [self __numberOfRightViewControllersDidChanged]; 583 | } 584 | 585 | - (void)_insertRightViewControllerViews { 586 | [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 587 | if (![self __isRightViewControllerAlreayInViewHierarchy:obj]) { 588 | UIViewController *viewController = obj; 589 | UIView *view = [self __loadViewForNewRightViewController:viewController]; 590 | [viewController viewWillAppear:NO]; 591 | [self.view addSubview:view]; 592 | view.center = CGPointZero; 593 | [viewController viewDidAppear:NO]; 594 | } 595 | }]; 596 | if (_indexOfFrontViewController < self.viewControllers.count) { 597 | [self __moveRightViewControllerToRightAnchorPoint:[self.viewControllers objectAtIndex:_indexOfFrontViewController] animated:NO]; 598 | 599 | [self __updateViewControllerShadows]; 600 | } 601 | } 602 | 603 | @end 604 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A75797EB13E1AD15008670B0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75797EA13E1AD15008670B0 /* UIKit.framework */; }; 11 | A75797ED13E1AD15008670B0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75797EC13E1AD15008670B0 /* Foundation.framework */; }; 12 | A75797EF13E1AD15008670B0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75797EE13E1AD15008670B0 /* CoreGraphics.framework */; }; 13 | A75797F513E1AD15008670B0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A75797F313E1AD15008670B0 /* InfoPlist.strings */; }; 14 | A75797F713E1AD15008670B0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A75797F613E1AD15008670B0 /* main.m */; }; 15 | A75797FB13E1AD15008670B0 /* SampleApplicationAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A75797FA13E1AD15008670B0 /* SampleApplicationAppDelegate.m */; }; 16 | A757981F13E1AEE3008670B0 /* LeftViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A757981E13E1AEE3008670B0 /* LeftViewController.m */; }; 17 | A757982213E1AF1A008670B0 /* RightViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A757982113E1AF1A008670B0 /* RightViewController.m */; }; 18 | A7B6549B13EA93E6009E4414 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7B6549A13EA93E6009E4414 /* QuartzCore.framework */; }; 19 | A7B654A713EA9425009E4414 /* libANAdvancedNavigationController.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A7B654A413EA9410009E4414 /* libANAdvancedNavigationController.a */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | A7B654A313EA9410009E4414 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = A7B6549C13EA9410009E4414 /* ANAdvancedNavigationController.xcodeproj */; 26 | proxyType = 2; 27 | remoteGlobalIDString = A7C3773213EA8EF800B9943A; 28 | remoteInfo = ANAdvancedNavigationController; 29 | }; 30 | A7B654A513EA941F009E4414 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = A7B6549C13EA9410009E4414 /* ANAdvancedNavigationController.xcodeproj */; 33 | proxyType = 1; 34 | remoteGlobalIDString = A7C3773113EA8EF800B9943A; 35 | remoteInfo = ANAdvancedNavigationController; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | A75797E613E1AD15008670B0 /* SampleApplication.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApplication.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | A75797EA13E1AD15008670B0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 42 | A75797EC13E1AD15008670B0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 43 | A75797EE13E1AD15008670B0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 44 | A75797F213E1AD15008670B0 /* SampleApplication-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SampleApplication-Info.plist"; sourceTree = ""; }; 45 | A75797F413E1AD15008670B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 46 | A75797F613E1AD15008670B0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | A75797F813E1AD15008670B0 /* SampleApplication-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SampleApplication-Prefix.pch"; sourceTree = ""; }; 48 | A75797F913E1AD15008670B0 /* SampleApplicationAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleApplicationAppDelegate.h; sourceTree = ""; }; 49 | A75797FA13E1AD15008670B0 /* SampleApplicationAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleApplicationAppDelegate.m; sourceTree = ""; }; 50 | A757981D13E1AEE3008670B0 /* LeftViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LeftViewController.h; sourceTree = ""; }; 51 | A757981E13E1AEE3008670B0 /* LeftViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LeftViewController.m; sourceTree = ""; }; 52 | A757982013E1AF1A008670B0 /* RightViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RightViewController.h; sourceTree = ""; }; 53 | A757982113E1AF1A008670B0 /* RightViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RightViewController.m; sourceTree = ""; }; 54 | A7B6549A13EA93E6009E4414 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 55 | A7B6549C13EA9410009E4414 /* ANAdvancedNavigationController.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ANAdvancedNavigationController.xcodeproj; sourceTree = SOURCE_ROOT; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | A75797E313E1AD15008670B0 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | A7B654A713EA9425009E4414 /* libANAdvancedNavigationController.a in Frameworks */, 64 | A7B6549B13EA93E6009E4414 /* QuartzCore.framework in Frameworks */, 65 | A75797EB13E1AD15008670B0 /* UIKit.framework in Frameworks */, 66 | A75797ED13E1AD15008670B0 /* Foundation.framework in Frameworks */, 67 | A75797EF13E1AD15008670B0 /* CoreGraphics.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXFrameworksBuildPhase section */ 72 | 73 | /* Begin PBXGroup section */ 74 | A75797DB13E1AD14008670B0 = { 75 | isa = PBXGroup; 76 | children = ( 77 | A75797F013E1AD15008670B0 /* SampleApplication */, 78 | A75797E913E1AD15008670B0 /* Frameworks */, 79 | A75797E713E1AD15008670B0 /* Products */, 80 | ); 81 | sourceTree = ""; 82 | }; 83 | A75797E713E1AD15008670B0 /* Products */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | A75797E613E1AD15008670B0 /* SampleApplication.app */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | A75797E913E1AD15008670B0 /* Frameworks */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | A7B6549A13EA93E6009E4414 /* QuartzCore.framework */, 95 | A75797EA13E1AD15008670B0 /* UIKit.framework */, 96 | A75797EC13E1AD15008670B0 /* Foundation.framework */, 97 | A75797EE13E1AD15008670B0 /* CoreGraphics.framework */, 98 | ); 99 | name = Frameworks; 100 | sourceTree = ""; 101 | }; 102 | A75797F013E1AD15008670B0 /* SampleApplication */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | A757981C13E1AEE3008670B0 /* ViewControllers */, 106 | A757980513E1ADCC008670B0 /* ANAdvancedNavigationController */, 107 | A75797F913E1AD15008670B0 /* SampleApplicationAppDelegate.h */, 108 | A75797FA13E1AD15008670B0 /* SampleApplicationAppDelegate.m */, 109 | A75797F113E1AD15008670B0 /* Supporting Files */, 110 | ); 111 | path = SampleApplication; 112 | sourceTree = ""; 113 | }; 114 | A75797F113E1AD15008670B0 /* Supporting Files */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | A75797F213E1AD15008670B0 /* SampleApplication-Info.plist */, 118 | A75797F313E1AD15008670B0 /* InfoPlist.strings */, 119 | A75797F613E1AD15008670B0 /* main.m */, 120 | A75797F813E1AD15008670B0 /* SampleApplication-Prefix.pch */, 121 | ); 122 | name = "Supporting Files"; 123 | sourceTree = ""; 124 | }; 125 | A757980513E1ADCC008670B0 /* ANAdvancedNavigationController */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | A7B6549C13EA9410009E4414 /* ANAdvancedNavigationController.xcodeproj */, 129 | ); 130 | name = ANAdvancedNavigationController; 131 | path = ../../ANAdvancedNavigationController; 132 | sourceTree = ""; 133 | }; 134 | A757981C13E1AEE3008670B0 /* ViewControllers */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | A757981D13E1AEE3008670B0 /* LeftViewController.h */, 138 | A757981E13E1AEE3008670B0 /* LeftViewController.m */, 139 | A757982013E1AF1A008670B0 /* RightViewController.h */, 140 | A757982113E1AF1A008670B0 /* RightViewController.m */, 141 | ); 142 | path = ViewControllers; 143 | sourceTree = ""; 144 | }; 145 | A7B6549D13EA9410009E4414 /* Products */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | A7B654A413EA9410009E4414 /* libANAdvancedNavigationController.a */, 149 | ); 150 | name = Products; 151 | sourceTree = ""; 152 | }; 153 | /* End PBXGroup section */ 154 | 155 | /* Begin PBXNativeTarget section */ 156 | A75797E513E1AD15008670B0 /* SampleApplication */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = A75797FE13E1AD15008670B0 /* Build configuration list for PBXNativeTarget "SampleApplication" */; 159 | buildPhases = ( 160 | A75797E213E1AD15008670B0 /* Sources */, 161 | A75797E313E1AD15008670B0 /* Frameworks */, 162 | A75797E413E1AD15008670B0 /* Resources */, 163 | ); 164 | buildRules = ( 165 | ); 166 | dependencies = ( 167 | A7B654A613EA941F009E4414 /* PBXTargetDependency */, 168 | ); 169 | name = SampleApplication; 170 | productName = SampleApplication; 171 | productReference = A75797E613E1AD15008670B0 /* SampleApplication.app */; 172 | productType = "com.apple.product-type.application"; 173 | }; 174 | /* End PBXNativeTarget section */ 175 | 176 | /* Begin PBXProject section */ 177 | A75797DD13E1AD14008670B0 /* Project object */ = { 178 | isa = PBXProject; 179 | attributes = { 180 | LastUpgradeCheck = 0420; 181 | ORGANIZATIONNAME = Home; 182 | }; 183 | buildConfigurationList = A75797E013E1AD14008670B0 /* Build configuration list for PBXProject "SampleApplication" */; 184 | compatibilityVersion = "Xcode 3.2"; 185 | developmentRegion = English; 186 | hasScannedForEncodings = 0; 187 | knownRegions = ( 188 | en, 189 | ); 190 | mainGroup = A75797DB13E1AD14008670B0; 191 | productRefGroup = A75797E713E1AD15008670B0 /* Products */; 192 | projectDirPath = ""; 193 | projectReferences = ( 194 | { 195 | ProductGroup = A7B6549D13EA9410009E4414 /* Products */; 196 | ProjectRef = A7B6549C13EA9410009E4414 /* ANAdvancedNavigationController.xcodeproj */; 197 | }, 198 | ); 199 | projectRoot = ""; 200 | targets = ( 201 | A75797E513E1AD15008670B0 /* SampleApplication */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXReferenceProxy section */ 207 | A7B654A413EA9410009E4414 /* libANAdvancedNavigationController.a */ = { 208 | isa = PBXReferenceProxy; 209 | fileType = archive.ar; 210 | path = libANAdvancedNavigationController.a; 211 | remoteRef = A7B654A313EA9410009E4414 /* PBXContainerItemProxy */; 212 | sourceTree = BUILT_PRODUCTS_DIR; 213 | }; 214 | /* End PBXReferenceProxy section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | A75797E413E1AD15008670B0 /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | A75797F513E1AD15008670B0 /* InfoPlist.strings in Resources */, 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | }; 225 | /* End PBXResourcesBuildPhase section */ 226 | 227 | /* Begin PBXSourcesBuildPhase section */ 228 | A75797E213E1AD15008670B0 /* Sources */ = { 229 | isa = PBXSourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | A75797F713E1AD15008670B0 /* main.m in Sources */, 233 | A75797FB13E1AD15008670B0 /* SampleApplicationAppDelegate.m in Sources */, 234 | A757981F13E1AEE3008670B0 /* LeftViewController.m in Sources */, 235 | A757982213E1AF1A008670B0 /* RightViewController.m in Sources */, 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | }; 239 | /* End PBXSourcesBuildPhase section */ 240 | 241 | /* Begin PBXTargetDependency section */ 242 | A7B654A613EA941F009E4414 /* PBXTargetDependency */ = { 243 | isa = PBXTargetDependency; 244 | name = ANAdvancedNavigationController; 245 | targetProxy = A7B654A513EA941F009E4414 /* PBXContainerItemProxy */; 246 | }; 247 | /* End PBXTargetDependency section */ 248 | 249 | /* Begin PBXVariantGroup section */ 250 | A75797F313E1AD15008670B0 /* InfoPlist.strings */ = { 251 | isa = PBXVariantGroup; 252 | children = ( 253 | A75797F413E1AD15008670B0 /* en */, 254 | ); 255 | name = InfoPlist.strings; 256 | sourceTree = ""; 257 | }; 258 | /* End PBXVariantGroup section */ 259 | 260 | /* Begin XCBuildConfiguration section */ 261 | A75797FC13E1AD15008670B0 /* Debug */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 266 | CLANG_ENABLE_OBJC_ARC = YES; 267 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 268 | COPY_PHASE_STRIP = NO; 269 | GCC_C_LANGUAGE_STANDARD = gnu99; 270 | GCC_DYNAMIC_NO_PIC = NO; 271 | GCC_OPTIMIZATION_LEVEL = 0; 272 | GCC_PREPROCESSOR_DEFINITIONS = ( 273 | "DEBUG=1", 274 | "$(inherited)", 275 | ); 276 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 277 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 278 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 280 | GCC_WARN_UNUSED_VARIABLE = YES; 281 | HEADER_SEARCH_PATHS = "ANAdvancedNavigationController/**"; 282 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 283 | LIBRARY_SEARCH_PATHS = "ANAdvancedNavigationController/**"; 284 | OTHER_LDFLAGS = ( 285 | "-Objc", 286 | "-all_load", 287 | ); 288 | SDKROOT = iphoneos; 289 | TARGETED_DEVICE_FAMILY = 2; 290 | }; 291 | name = Debug; 292 | }; 293 | A75797FD13E1AD15008670B0 /* Release */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ALWAYS_SEARCH_USER_PATHS = NO; 297 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 298 | CLANG_ENABLE_OBJC_ARC = YES; 299 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 300 | COPY_PHASE_STRIP = YES; 301 | GCC_C_LANGUAGE_STANDARD = gnu99; 302 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 303 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 304 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 305 | GCC_WARN_UNUSED_VARIABLE = YES; 306 | HEADER_SEARCH_PATHS = "ANAdvancedNavigationController/**"; 307 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 308 | LIBRARY_SEARCH_PATHS = "ANAdvancedNavigationController/**"; 309 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 310 | OTHER_LDFLAGS = ( 311 | "-Objc", 312 | "-all_load", 313 | ); 314 | SDKROOT = iphoneos; 315 | TARGETED_DEVICE_FAMILY = 2; 316 | VALIDATE_PRODUCT = YES; 317 | }; 318 | name = Release; 319 | }; 320 | A75797FF13E1AD15008670B0 /* Debug */ = { 321 | isa = XCBuildConfiguration; 322 | buildSettings = { 323 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 324 | GCC_PREFIX_HEADER = "SampleApplication/SampleApplication-Prefix.pch"; 325 | INFOPLIST_FILE = "SampleApplication/SampleApplication-Info.plist"; 326 | PRODUCT_NAME = "$(TARGET_NAME)"; 327 | WRAPPER_EXTENSION = app; 328 | }; 329 | name = Debug; 330 | }; 331 | A757980013E1AD15008670B0 /* Release */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 335 | GCC_PREFIX_HEADER = "SampleApplication/SampleApplication-Prefix.pch"; 336 | INFOPLIST_FILE = "SampleApplication/SampleApplication-Info.plist"; 337 | PRODUCT_NAME = "$(TARGET_NAME)"; 338 | WRAPPER_EXTENSION = app; 339 | }; 340 | name = Release; 341 | }; 342 | /* End XCBuildConfiguration section */ 343 | 344 | /* Begin XCConfigurationList section */ 345 | A75797E013E1AD14008670B0 /* Build configuration list for PBXProject "SampleApplication" */ = { 346 | isa = XCConfigurationList; 347 | buildConfigurations = ( 348 | A75797FC13E1AD15008670B0 /* Debug */, 349 | A75797FD13E1AD15008670B0 /* Release */, 350 | ); 351 | defaultConfigurationIsVisible = 0; 352 | defaultConfigurationName = Release; 353 | }; 354 | A75797FE13E1AD15008670B0 /* Build configuration list for PBXNativeTarget "SampleApplication" */ = { 355 | isa = XCConfigurationList; 356 | buildConfigurations = ( 357 | A75797FF13E1AD15008670B0 /* Debug */, 358 | A757980013E1AD15008670B0 /* Release */, 359 | ); 360 | defaultConfigurationIsVisible = 0; 361 | defaultConfigurationName = Release; 362 | }; 363 | /* End XCConfigurationList section */ 364 | }; 365 | rootObject = A75797DD13E1AD14008670B0 /* Project object */; 366 | } 367 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/SampleApplication-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | de.ANAdvancedNavigationController.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UISupportedInterfaceOrientations~ipad 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationPortraitUpsideDown 33 | UIInterfaceOrientationLandscapeLeft 34 | UIInterfaceOrientationLandscapeRight 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/SampleApplication-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SampleApplication' target in the 'SampleApplication' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/SampleApplicationAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SampleApplicationAppDelegate.h 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SampleApplicationAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/SampleApplicationAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SampleApplicationAppDelegate.m 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "SampleApplicationAppDelegate.h" 10 | #import "ANAdvancedNavigationController.h" 11 | #import "LeftViewController.h" 12 | 13 | @implementation SampleApplicationAppDelegate 14 | @synthesize window = _window; 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | // Override point for customization after application launch. 19 | self.window.backgroundColor = [UIColor whiteColor]; 20 | 21 | LeftViewController *leftViewController = [[LeftViewController alloc] initWithStyle:UITableViewStyleGrouped]; 22 | ANAdvancedNavigationController *navigationController = [[ANAdvancedNavigationController alloc] initWithLeftViewController:leftViewController]; 23 | 24 | self.window.rootViewController = navigationController; 25 | 26 | [self.window makeKeyAndVisible]; 27 | return YES; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/ViewControllers/LeftViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LeftViewController.h 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface LeftViewController : UITableViewController { 13 | @private 14 | 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/ViewControllers/LeftViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LeftViewController.m 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "LeftViewController.h" 10 | #import "ANAdvancedNavigationController.h" 11 | #import "RightViewController.h" 12 | 13 | @implementation LeftViewController 14 | 15 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 16 | // Return YES for supported orientations 17 | return YES; 18 | } 19 | 20 | #pragma mark - Table view data source 21 | 22 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 23 | return 3; 24 | } 25 | 26 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 27 | return 5; 28 | } 29 | 30 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 31 | static NSString *CellIdentifier = @"Cell"; 32 | 33 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 34 | if (cell == nil) { 35 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 36 | } 37 | 38 | cell.textLabel.text = [NSString stringWithFormat:@"Section: %d, Row: %d", indexPath.section, indexPath.row]; 39 | 40 | return cell; 41 | } 42 | 43 | #pragma mark - Table view delegate 44 | 45 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 46 | RightViewController *viewController = [[RightViewController alloc] initWithStyle:UITableViewStyleGrouped]; 47 | [self.advancedNavigationController pushViewController:viewController afterViewController:nil animated:YES]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/ViewControllers/RightViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RightViewController.h 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface RightViewController : UITableViewController { 13 | @private 14 | 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/ViewControllers/RightViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RightViewController.m 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import "RightViewController.h" 10 | #import "ANAdvancedNavigationController.h" 11 | 12 | @implementation RightViewController 13 | 14 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 15 | // Return YES for supported orientations 16 | return YES; 17 | } 18 | 19 | #pragma mark - Table view data source 20 | 21 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 22 | // Return the number of sections. 23 | return 5; 24 | } 25 | 26 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 27 | // Return the number of rows in the section. 28 | return 3; 29 | } 30 | 31 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 32 | static NSString *CellIdentifier = @"Cell"; 33 | 34 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 35 | if (cell == nil) { 36 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 37 | } 38 | 39 | cell.textLabel.text = [NSString stringWithFormat:@"Section: %d, Row: %d", indexPath.section, indexPath.row]; 40 | 41 | return cell; 42 | } 43 | 44 | #pragma mark - Table view delegate 45 | 46 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 47 | RightViewController *viewController = [[RightViewController alloc] initWithStyle:UITableViewStyleGrouped]; 48 | [self.advancedNavigationController pushViewController:viewController afterViewController:self animated:YES]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /SampleApplication/SampleApplication/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SampleApplication 4 | // 5 | // Created by Oliver Letterer on 28.07.11. 6 | // Copyright 2011 Home. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SampleApplicationAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SampleApplicationAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Screenshots/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OliverLetterer/ANAdvancedNavigationController/c4eb06a6062561ea8e51e8d7781402778ed3ea21/Screenshots/1.jpg -------------------------------------------------------------------------------- /Screenshots/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OliverLetterer/ANAdvancedNavigationController/c4eb06a6062561ea8e51e8d7781402778ed3ea21/Screenshots/2.jpg --------------------------------------------------------------------------------