├── .gitignore ├── BTBreadcumbView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── meiwin.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── meiwin.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── Classes ├── BTBreadcrumbView.h └── BTBreadcrumbView.m ├── Demo ├── BTAppDelegate.h ├── BTAppDelegate.m ├── BTBreadcumbView-Info.plist ├── BTBreadcumbView-Prefix.pch ├── BTViewController.h ├── BTViewController.m ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── en.lproj │ ├── BTViewController.xib │ └── InfoPlist.strings └── main.m ├── README.md ├── Resources ├── breadcrumb_design.png ├── breadcrumb_design.psd ├── breadcrumb_design@2x.png ├── button_item.png ├── button_item.psd ├── button_item@2x.png ├── button_item@2x.psd ├── button_start.png ├── button_start.psd ├── button_start@2x.png └── button_start@2x.psd ├── Tests ├── BTFloatingMenuTests-Info.plist ├── BTFloatingMenuTests.h ├── BTFloatingMenuTests.m └── en.lproj │ └── InfoPlist.strings └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Exclude the build directory 2 | build/* 3 | 4 | # Exclude temp nibs and swap files 5 | *~.nib 6 | *.swp 7 | 8 | # Exclude OS X folder attributes 9 | .DS_Store 10 | 11 | # Exclude user-specific XCode 3 and 4 files 12 | *.mode1 13 | *.mode1v3 14 | *.mode2v3 15 | *.perspective 16 | *.perspectivev3 17 | *.pbxuser 18 | xcuserdata -------------------------------------------------------------------------------- /BTBreadcumbView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3D68E3D716A11987000F24C6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E3D616A11987000F24C6 /* UIKit.framework */; }; 11 | 3D68E3D916A11987000F24C6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E3D816A11987000F24C6 /* Foundation.framework */; }; 12 | 3D68E3DB16A11987000F24C6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E3DA16A11987000F24C6 /* CoreGraphics.framework */; }; 13 | 3D68E3E116A11987000F24C6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E3DF16A11987000F24C6 /* InfoPlist.strings */; }; 14 | 3D68E3E316A11987000F24C6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D68E3E216A11987000F24C6 /* main.m */; }; 15 | 3D68E3E716A11987000F24C6 /* BTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D68E3E616A11987000F24C6 /* BTAppDelegate.m */; }; 16 | 3D68E3E916A11987000F24C6 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E3E816A11987000F24C6 /* Default.png */; }; 17 | 3D68E3EB16A11987000F24C6 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E3EA16A11987000F24C6 /* Default@2x.png */; }; 18 | 3D68E3ED16A11987000F24C6 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E3EC16A11987000F24C6 /* Default-568h@2x.png */; }; 19 | 3D68E3F016A11987000F24C6 /* BTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D68E3EF16A11987000F24C6 /* BTViewController.m */; }; 20 | 3D68E3F316A11987000F24C6 /* BTViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E3F116A11987000F24C6 /* BTViewController.xib */; }; 21 | 3D68E3FB16A11988000F24C6 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E3FA16A11988000F24C6 /* SenTestingKit.framework */; }; 22 | 3D68E3FC16A11988000F24C6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E3D616A11987000F24C6 /* UIKit.framework */; }; 23 | 3D68E3FD16A11988000F24C6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E3D816A11987000F24C6 /* Foundation.framework */; }; 24 | 3D68E40516A11988000F24C6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E40316A11988000F24C6 /* InfoPlist.strings */; }; 25 | 3D68E40816A11988000F24C6 /* BTFloatingMenuTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D68E40716A11988000F24C6 /* BTFloatingMenuTests.m */; }; 26 | 3D68E41616A14DEC000F24C6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D68E41516A14DEC000F24C6 /* QuartzCore.framework */; }; 27 | 3D68E41A16A16508000F24C6 /* button_start.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E41816A16508000F24C6 /* button_start.png */; }; 28 | 3D68E41B16A16508000F24C6 /* button_start@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E41916A16508000F24C6 /* button_start@2x.png */; }; 29 | 3D68E42616A29576000F24C6 /* BTBreadcrumbView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D68E42516A29576000F24C6 /* BTBreadcrumbView.m */; }; 30 | 3D68E42916A2A417000F24C6 /* button_item.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E42716A2A417000F24C6 /* button_item.png */; }; 31 | 3D68E42A16A2A417000F24C6 /* button_item@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D68E42816A2A417000F24C6 /* button_item@2x.png */; }; 32 | 3D97B51F16A3099B00F2ACB1 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 3D97B51D16A3099B00F2ACB1 /* README.md */; }; 33 | 3D97B52016A3099B00F2ACB1 /* screenshot.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D97B51E16A3099B00F2ACB1 /* screenshot.png */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | 3D68E3FE16A11988000F24C6 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 3D68E3C916A11987000F24C6 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 3D68E3D116A11987000F24C6; 42 | remoteInfo = BTFloatingMenu; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 3D68E3D216A11987000F24C6 /* BTBreadcumbView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BTBreadcumbView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 3D68E3D616A11987000F24C6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 49 | 3D68E3D816A11987000F24C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 50 | 3D68E3DA16A11987000F24C6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 51 | 3D68E3DE16A11987000F24C6 /* BTBreadcumbView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "BTBreadcumbView-Info.plist"; sourceTree = ""; }; 52 | 3D68E3E016A11987000F24C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 53 | 3D68E3E216A11987000F24C6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 3D68E3E416A11987000F24C6 /* BTBreadcumbView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BTBreadcumbView-Prefix.pch"; sourceTree = ""; }; 55 | 3D68E3E516A11987000F24C6 /* BTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTAppDelegate.h; sourceTree = ""; }; 56 | 3D68E3E616A11987000F24C6 /* BTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BTAppDelegate.m; sourceTree = ""; }; 57 | 3D68E3E816A11987000F24C6 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 58 | 3D68E3EA16A11987000F24C6 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 59 | 3D68E3EC16A11987000F24C6 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 60 | 3D68E3EE16A11987000F24C6 /* BTViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTViewController.h; sourceTree = ""; }; 61 | 3D68E3EF16A11987000F24C6 /* BTViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BTViewController.m; sourceTree = ""; }; 62 | 3D68E3F216A11987000F24C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/BTViewController.xib; sourceTree = ""; }; 63 | 3D68E3F916A11988000F24C6 /* BTBreadcumbViewTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BTBreadcumbViewTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 3D68E3FA16A11988000F24C6 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 65 | 3D68E40216A11988000F24C6 /* BTFloatingMenuTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "BTFloatingMenuTests-Info.plist"; sourceTree = ""; }; 66 | 3D68E40416A11988000F24C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 67 | 3D68E40616A11988000F24C6 /* BTFloatingMenuTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTFloatingMenuTests.h; sourceTree = ""; }; 68 | 3D68E40716A11988000F24C6 /* BTFloatingMenuTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BTFloatingMenuTests.m; sourceTree = ""; }; 69 | 3D68E41516A14DEC000F24C6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 70 | 3D68E41816A16508000F24C6 /* button_start.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = button_start.png; sourceTree = ""; }; 71 | 3D68E41916A16508000F24C6 /* button_start@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_start@2x.png"; sourceTree = ""; }; 72 | 3D68E42416A29576000F24C6 /* BTBreadcrumbView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTBreadcrumbView.h; sourceTree = ""; }; 73 | 3D68E42516A29576000F24C6 /* BTBreadcrumbView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTBreadcrumbView.m; sourceTree = ""; }; 74 | 3D68E42716A2A417000F24C6 /* button_item.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = button_item.png; sourceTree = ""; }; 75 | 3D68E42816A2A417000F24C6 /* button_item@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_item@2x.png"; sourceTree = ""; }; 76 | 3D97B51D16A3099B00F2ACB1 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; 77 | 3D97B51E16A3099B00F2ACB1 /* screenshot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = screenshot.png; sourceTree = ""; }; 78 | /* End PBXFileReference section */ 79 | 80 | /* Begin PBXFrameworksBuildPhase section */ 81 | 3D68E3CF16A11987000F24C6 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | 3D68E41616A14DEC000F24C6 /* QuartzCore.framework in Frameworks */, 86 | 3D68E3D716A11987000F24C6 /* UIKit.framework in Frameworks */, 87 | 3D68E3D916A11987000F24C6 /* Foundation.framework in Frameworks */, 88 | 3D68E3DB16A11987000F24C6 /* CoreGraphics.framework in Frameworks */, 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | 3D68E3F516A11987000F24C6 /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | 3D68E3FB16A11988000F24C6 /* SenTestingKit.framework in Frameworks */, 97 | 3D68E3FC16A11988000F24C6 /* UIKit.framework in Frameworks */, 98 | 3D68E3FD16A11988000F24C6 /* Foundation.framework in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 3D68E3C716A11987000F24C6 = { 106 | isa = PBXGroup; 107 | children = ( 108 | 3D97B51D16A3099B00F2ACB1 /* README.md */, 109 | 3D97B51E16A3099B00F2ACB1 /* screenshot.png */, 110 | 3D68E41716A164EF000F24C6 /* Resources */, 111 | 3D68E41116A11C9E000F24C6 /* Classes */, 112 | 3D68E3DC16A11987000F24C6 /* Demo */, 113 | 3D68E40016A11988000F24C6 /* BTFloatingMenuTests */, 114 | 3D68E3D516A11987000F24C6 /* Frameworks */, 115 | 3D68E3D316A11987000F24C6 /* Products */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 3D68E3D316A11987000F24C6 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 3D68E3D216A11987000F24C6 /* BTBreadcumbView.app */, 123 | 3D68E3F916A11988000F24C6 /* BTBreadcumbViewTests.octest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | 3D68E3D516A11987000F24C6 /* Frameworks */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 3D68E41516A14DEC000F24C6 /* QuartzCore.framework */, 132 | 3D68E3D616A11987000F24C6 /* UIKit.framework */, 133 | 3D68E3D816A11987000F24C6 /* Foundation.framework */, 134 | 3D68E3DA16A11987000F24C6 /* CoreGraphics.framework */, 135 | 3D68E3FA16A11988000F24C6 /* SenTestingKit.framework */, 136 | ); 137 | name = Frameworks; 138 | sourceTree = ""; 139 | }; 140 | 3D68E3DC16A11987000F24C6 /* Demo */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 3D68E3E516A11987000F24C6 /* BTAppDelegate.h */, 144 | 3D68E3E616A11987000F24C6 /* BTAppDelegate.m */, 145 | 3D68E3EE16A11987000F24C6 /* BTViewController.h */, 146 | 3D68E3EF16A11987000F24C6 /* BTViewController.m */, 147 | 3D68E3F116A11987000F24C6 /* BTViewController.xib */, 148 | 3D68E3DD16A11987000F24C6 /* Supporting Files */, 149 | ); 150 | path = Demo; 151 | sourceTree = ""; 152 | }; 153 | 3D68E3DD16A11987000F24C6 /* Supporting Files */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 3D68E3DE16A11987000F24C6 /* BTBreadcumbView-Info.plist */, 157 | 3D68E3DF16A11987000F24C6 /* InfoPlist.strings */, 158 | 3D68E3E216A11987000F24C6 /* main.m */, 159 | 3D68E3E416A11987000F24C6 /* BTBreadcumbView-Prefix.pch */, 160 | 3D68E3E816A11987000F24C6 /* Default.png */, 161 | 3D68E3EA16A11987000F24C6 /* Default@2x.png */, 162 | 3D68E3EC16A11987000F24C6 /* Default-568h@2x.png */, 163 | ); 164 | name = "Supporting Files"; 165 | sourceTree = ""; 166 | }; 167 | 3D68E40016A11988000F24C6 /* BTFloatingMenuTests */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 3D68E40616A11988000F24C6 /* BTFloatingMenuTests.h */, 171 | 3D68E40716A11988000F24C6 /* BTFloatingMenuTests.m */, 172 | 3D68E40116A11988000F24C6 /* Supporting Files */, 173 | ); 174 | name = BTFloatingMenuTests; 175 | path = Tests; 176 | sourceTree = ""; 177 | }; 178 | 3D68E40116A11988000F24C6 /* Supporting Files */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 3D68E40216A11988000F24C6 /* BTFloatingMenuTests-Info.plist */, 182 | 3D68E40316A11988000F24C6 /* InfoPlist.strings */, 183 | ); 184 | name = "Supporting Files"; 185 | sourceTree = ""; 186 | }; 187 | 3D68E41116A11C9E000F24C6 /* Classes */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 3D68E42416A29576000F24C6 /* BTBreadcrumbView.h */, 191 | 3D68E42516A29576000F24C6 /* BTBreadcrumbView.m */, 192 | ); 193 | path = Classes; 194 | sourceTree = ""; 195 | }; 196 | 3D68E41716A164EF000F24C6 /* Resources */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 3D68E42716A2A417000F24C6 /* button_item.png */, 200 | 3D68E42816A2A417000F24C6 /* button_item@2x.png */, 201 | 3D68E41816A16508000F24C6 /* button_start.png */, 202 | 3D68E41916A16508000F24C6 /* button_start@2x.png */, 203 | ); 204 | path = Resources; 205 | sourceTree = ""; 206 | }; 207 | /* End PBXGroup section */ 208 | 209 | /* Begin PBXNativeTarget section */ 210 | 3D68E3D116A11987000F24C6 /* BTBreadcumbView */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 3D68E40B16A11988000F24C6 /* Build configuration list for PBXNativeTarget "BTBreadcumbView" */; 213 | buildPhases = ( 214 | 3D68E3CE16A11987000F24C6 /* Sources */, 215 | 3D68E3CF16A11987000F24C6 /* Frameworks */, 216 | 3D68E3D016A11987000F24C6 /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | ); 222 | name = BTBreadcumbView; 223 | productName = BTFloatingMenu; 224 | productReference = 3D68E3D216A11987000F24C6 /* BTBreadcumbView.app */; 225 | productType = "com.apple.product-type.application"; 226 | }; 227 | 3D68E3F816A11987000F24C6 /* BTBreadcumbViewTests */ = { 228 | isa = PBXNativeTarget; 229 | buildConfigurationList = 3D68E40E16A11988000F24C6 /* Build configuration list for PBXNativeTarget "BTBreadcumbViewTests" */; 230 | buildPhases = ( 231 | 3D68E3F416A11987000F24C6 /* Sources */, 232 | 3D68E3F516A11987000F24C6 /* Frameworks */, 233 | 3D68E3F616A11987000F24C6 /* Resources */, 234 | 3D68E3F716A11987000F24C6 /* ShellScript */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | 3D68E3FF16A11988000F24C6 /* PBXTargetDependency */, 240 | ); 241 | name = BTBreadcumbViewTests; 242 | productName = BTFloatingMenuTests; 243 | productReference = 3D68E3F916A11988000F24C6 /* BTBreadcumbViewTests.octest */; 244 | productType = "com.apple.product-type.bundle"; 245 | }; 246 | /* End PBXNativeTarget section */ 247 | 248 | /* Begin PBXProject section */ 249 | 3D68E3C916A11987000F24C6 /* Project object */ = { 250 | isa = PBXProject; 251 | attributes = { 252 | CLASSPREFIX = BT; 253 | LastUpgradeCheck = 0450; 254 | ORGANIZATIONNAME = BlockThirty; 255 | }; 256 | buildConfigurationList = 3D68E3CC16A11987000F24C6 /* Build configuration list for PBXProject "BTBreadcumbView" */; 257 | compatibilityVersion = "Xcode 3.2"; 258 | developmentRegion = English; 259 | hasScannedForEncodings = 0; 260 | knownRegions = ( 261 | en, 262 | ); 263 | mainGroup = 3D68E3C716A11987000F24C6; 264 | productRefGroup = 3D68E3D316A11987000F24C6 /* Products */; 265 | projectDirPath = ""; 266 | projectRoot = ""; 267 | targets = ( 268 | 3D68E3D116A11987000F24C6 /* BTBreadcumbView */, 269 | 3D68E3F816A11987000F24C6 /* BTBreadcumbViewTests */, 270 | ); 271 | }; 272 | /* End PBXProject section */ 273 | 274 | /* Begin PBXResourcesBuildPhase section */ 275 | 3D68E3D016A11987000F24C6 /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 3D68E3E116A11987000F24C6 /* InfoPlist.strings in Resources */, 280 | 3D68E3E916A11987000F24C6 /* Default.png in Resources */, 281 | 3D68E3EB16A11987000F24C6 /* Default@2x.png in Resources */, 282 | 3D68E3ED16A11987000F24C6 /* Default-568h@2x.png in Resources */, 283 | 3D68E3F316A11987000F24C6 /* BTViewController.xib in Resources */, 284 | 3D68E41A16A16508000F24C6 /* button_start.png in Resources */, 285 | 3D68E41B16A16508000F24C6 /* button_start@2x.png in Resources */, 286 | 3D68E42916A2A417000F24C6 /* button_item.png in Resources */, 287 | 3D68E42A16A2A417000F24C6 /* button_item@2x.png in Resources */, 288 | 3D97B51F16A3099B00F2ACB1 /* README.md in Resources */, 289 | 3D97B52016A3099B00F2ACB1 /* screenshot.png in Resources */, 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | }; 293 | 3D68E3F616A11987000F24C6 /* Resources */ = { 294 | isa = PBXResourcesBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | 3D68E40516A11988000F24C6 /* InfoPlist.strings in Resources */, 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | }; 301 | /* End PBXResourcesBuildPhase section */ 302 | 303 | /* Begin PBXShellScriptBuildPhase section */ 304 | 3D68E3F716A11987000F24C6 /* ShellScript */ = { 305 | isa = PBXShellScriptBuildPhase; 306 | buildActionMask = 2147483647; 307 | files = ( 308 | ); 309 | inputPaths = ( 310 | ); 311 | outputPaths = ( 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | shellPath = /bin/sh; 315 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 316 | }; 317 | /* End PBXShellScriptBuildPhase section */ 318 | 319 | /* Begin PBXSourcesBuildPhase section */ 320 | 3D68E3CE16A11987000F24C6 /* Sources */ = { 321 | isa = PBXSourcesBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | 3D68E3E316A11987000F24C6 /* main.m in Sources */, 325 | 3D68E3E716A11987000F24C6 /* BTAppDelegate.m in Sources */, 326 | 3D68E3F016A11987000F24C6 /* BTViewController.m in Sources */, 327 | 3D68E42616A29576000F24C6 /* BTBreadcrumbView.m in Sources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | 3D68E3F416A11987000F24C6 /* Sources */ = { 332 | isa = PBXSourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | 3D68E40816A11988000F24C6 /* BTFloatingMenuTests.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | /* End PBXSourcesBuildPhase section */ 340 | 341 | /* Begin PBXTargetDependency section */ 342 | 3D68E3FF16A11988000F24C6 /* PBXTargetDependency */ = { 343 | isa = PBXTargetDependency; 344 | target = 3D68E3D116A11987000F24C6 /* BTBreadcumbView */; 345 | targetProxy = 3D68E3FE16A11988000F24C6 /* PBXContainerItemProxy */; 346 | }; 347 | /* End PBXTargetDependency section */ 348 | 349 | /* Begin PBXVariantGroup section */ 350 | 3D68E3DF16A11987000F24C6 /* InfoPlist.strings */ = { 351 | isa = PBXVariantGroup; 352 | children = ( 353 | 3D68E3E016A11987000F24C6 /* en */, 354 | ); 355 | name = InfoPlist.strings; 356 | sourceTree = ""; 357 | }; 358 | 3D68E3F116A11987000F24C6 /* BTViewController.xib */ = { 359 | isa = PBXVariantGroup; 360 | children = ( 361 | 3D68E3F216A11987000F24C6 /* en */, 362 | ); 363 | name = BTViewController.xib; 364 | sourceTree = ""; 365 | }; 366 | 3D68E40316A11988000F24C6 /* InfoPlist.strings */ = { 367 | isa = PBXVariantGroup; 368 | children = ( 369 | 3D68E40416A11988000F24C6 /* en */, 370 | ); 371 | name = InfoPlist.strings; 372 | sourceTree = ""; 373 | }; 374 | /* End PBXVariantGroup section */ 375 | 376 | /* Begin XCBuildConfiguration section */ 377 | 3D68E40916A11988000F24C6 /* Debug */ = { 378 | isa = XCBuildConfiguration; 379 | buildSettings = { 380 | ALWAYS_SEARCH_USER_PATHS = NO; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_OBJC_ARC = YES; 384 | CLANG_WARN_EMPTY_BODY = YES; 385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 386 | CODE_SIGN_IDENTITY = "iPhone Distribution: Meiwin Fu"; 387 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Meiwin Fu"; 388 | COPY_PHASE_STRIP = NO; 389 | GCC_C_LANGUAGE_STANDARD = gnu99; 390 | GCC_DYNAMIC_NO_PIC = NO; 391 | GCC_OPTIMIZATION_LEVEL = 0; 392 | GCC_PREPROCESSOR_DEFINITIONS = ( 393 | "DEBUG=1", 394 | "$(inherited)", 395 | ); 396 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 397 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 398 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 399 | GCC_WARN_UNUSED_VARIABLE = YES; 400 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 401 | ONLY_ACTIVE_ARCH = YES; 402 | PROVISIONING_PROFILE = "8852F747-2D5C-47F4-9190-275BD27A78AE"; 403 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = "8852F747-2D5C-47F4-9190-275BD27A78AE"; 404 | SDKROOT = iphoneos; 405 | TARGETED_DEVICE_FAMILY = 2; 406 | }; 407 | name = Debug; 408 | }; 409 | 3D68E40A16A11988000F24C6 /* Release */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_SEARCH_USER_PATHS = NO; 413 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_OBJC_ARC = YES; 416 | CLANG_WARN_EMPTY_BODY = YES; 417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 418 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 419 | COPY_PHASE_STRIP = YES; 420 | GCC_C_LANGUAGE_STANDARD = gnu99; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 422 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 423 | GCC_WARN_UNUSED_VARIABLE = YES; 424 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 425 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 426 | SDKROOT = iphoneos; 427 | TARGETED_DEVICE_FAMILY = 2; 428 | VALIDATE_PRODUCT = YES; 429 | }; 430 | name = Release; 431 | }; 432 | 3D68E40C16A11988000F24C6 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 436 | GCC_PREFIX_HEADER = "Demo/BTBreadcumbView-Prefix.pch"; 437 | INFOPLIST_FILE = "Demo/BTBreadcumbView-Info.plist"; 438 | PRODUCT_NAME = BTBreadcumbView; 439 | WRAPPER_EXTENSION = app; 440 | }; 441 | name = Debug; 442 | }; 443 | 3D68E40D16A11988000F24C6 /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 447 | GCC_PREFIX_HEADER = "Demo/BTBreadcumbView-Prefix.pch"; 448 | INFOPLIST_FILE = "Demo/BTBreadcumbView-Info.plist"; 449 | PRODUCT_NAME = BTBreadcumbView; 450 | WRAPPER_EXTENSION = app; 451 | }; 452 | name = Release; 453 | }; 454 | 3D68E40F16A11988000F24C6 /* Debug */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/BTFloatingMenu.app/BTFloatingMenu"; 458 | FRAMEWORK_SEARCH_PATHS = ( 459 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 460 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", 461 | ); 462 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 463 | GCC_PREFIX_HEADER = "BTFloatingMenu/BTFloatingMenu-Prefix.pch"; 464 | INFOPLIST_FILE = "BTFloatingMenuTests/BTFloatingMenuTests-Info.plist"; 465 | PRODUCT_NAME = BTBreadcumbViewTests; 466 | TEST_HOST = "$(BUNDLE_LOADER)"; 467 | WRAPPER_EXTENSION = octest; 468 | }; 469 | name = Debug; 470 | }; 471 | 3D68E41016A11988000F24C6 /* Release */ = { 472 | isa = XCBuildConfiguration; 473 | buildSettings = { 474 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/BTFloatingMenu.app/BTFloatingMenu"; 475 | FRAMEWORK_SEARCH_PATHS = ( 476 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 477 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", 478 | ); 479 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 480 | GCC_PREFIX_HEADER = "BTFloatingMenu/BTFloatingMenu-Prefix.pch"; 481 | INFOPLIST_FILE = "BTFloatingMenuTests/BTFloatingMenuTests-Info.plist"; 482 | PRODUCT_NAME = BTBreadcumbViewTests; 483 | TEST_HOST = "$(BUNDLE_LOADER)"; 484 | WRAPPER_EXTENSION = octest; 485 | }; 486 | name = Release; 487 | }; 488 | /* End XCBuildConfiguration section */ 489 | 490 | /* Begin XCConfigurationList section */ 491 | 3D68E3CC16A11987000F24C6 /* Build configuration list for PBXProject "BTBreadcumbView" */ = { 492 | isa = XCConfigurationList; 493 | buildConfigurations = ( 494 | 3D68E40916A11988000F24C6 /* Debug */, 495 | 3D68E40A16A11988000F24C6 /* Release */, 496 | ); 497 | defaultConfigurationIsVisible = 0; 498 | defaultConfigurationName = Release; 499 | }; 500 | 3D68E40B16A11988000F24C6 /* Build configuration list for PBXNativeTarget "BTBreadcumbView" */ = { 501 | isa = XCConfigurationList; 502 | buildConfigurations = ( 503 | 3D68E40C16A11988000F24C6 /* Debug */, 504 | 3D68E40D16A11988000F24C6 /* Release */, 505 | ); 506 | defaultConfigurationIsVisible = 0; 507 | defaultConfigurationName = Release; 508 | }; 509 | 3D68E40E16A11988000F24C6 /* Build configuration list for PBXNativeTarget "BTBreadcumbViewTests" */ = { 510 | isa = XCConfigurationList; 511 | buildConfigurations = ( 512 | 3D68E40F16A11988000F24C6 /* Debug */, 513 | 3D68E41016A11988000F24C6 /* Release */, 514 | ); 515 | defaultConfigurationIsVisible = 0; 516 | defaultConfigurationName = Release; 517 | }; 518 | /* End XCConfigurationList section */ 519 | }; 520 | rootObject = 3D68E3C916A11987000F24C6 /* Project object */; 521 | } 522 | -------------------------------------------------------------------------------- /BTBreadcumbView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BTBreadcumbView.xcodeproj/project.xcworkspace/xcuserdata/meiwin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/BTBreadcumbView.xcodeproj/project.xcworkspace/xcuserdata/meiwin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /BTBreadcumbView.xcodeproj/xcuserdata/meiwin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BTBreadcrumbView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 3D68E3D116A11987000F24C6 16 | 17 | primary 18 | 19 | 20 | 3D68E3F816A11987000F24C6 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Classes/BTBreadcrumbView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BTBreadcrumbView.h 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 13/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //////////////////////////////////////////////////////////////////////////////// 12 | //////////////////////////////////////////////////////////////////////////////// 13 | //////////////////////////////////////////////////////////////////////////////// 14 | @class BTBreadcrumbView; 15 | @protocol BTBreadcrumbViewDelegate 16 | @optional 17 | - (void)breadcrumbViewDidTapStartButton:(BTBreadcrumbView *)view; 18 | - (void)breadcrumbView:(BTBreadcrumbView *)view didTapItemAtIndex:(NSUInteger)index; 19 | @end 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | //////////////////////////////////////////////////////////////////////////////// 23 | //////////////////////////////////////////////////////////////////////////////// 24 | @interface BTBreadcrumbItem : NSObject 25 | @property (nonatomic,strong) NSString *title; 26 | @end 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | //////////////////////////////////////////////////////////////////////////////// 30 | //////////////////////////////////////////////////////////////////////////////// 31 | @interface BTBreadcrumbView : UIView 32 | { 33 | UIView *_containerView; 34 | UIButton *_startButton; 35 | NSArray * _items; 36 | NSMutableArray * _itemViews; 37 | 38 | BOOL _animating; 39 | __unsafe_unretained id _delegate; 40 | } 41 | @property (nonatomic,strong) NSArray *items; 42 | @property (nonatomic,assign) id delegate; 43 | 44 | - (void)setItems:(NSArray *)items; 45 | - (void)setItems:(NSArray *)items animated:(BOOL)animated; 46 | @end 47 | 48 | -------------------------------------------------------------------------------- /Classes/BTBreadcrumbView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BTBreadcrumbView.m 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 13/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import "BTBreadcrumbView.h" 10 | #import 11 | 12 | #define kAnimationDuration 0.5 13 | 14 | #define kShadowOpacity 0.3 15 | #define kShadowOffset CGSizeMake(1, 2) 16 | #define kShadowRadius 2.5 17 | #define kShadowColor [UIColor blackColor].CGColor 18 | 19 | #define mSetShadow(_view) \ 20 | CALayer *layer = [_view layer]; \ 21 | layer.shadowOffset = kShadowOffset; \ 22 | layer.shadowOpacity = kShadowOpacity; \ 23 | layer.shadowRadius = kShadowRadius; \ 24 | layer.shadowColor = kShadowColor 25 | 26 | #define mRGBA(_red,_green,_blue,_alpha) \ 27 | [UIColor colorWithRed:(_red/255.0) green:(_green/255.0) blue:(_blue/255.0) alpha:_alpha] 28 | 29 | #define mRect(_w,_h) CGRectMake(0,0,_w,_h) 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | //////////////////////////////////////////////////////////////////////////////// 33 | //////////////////////////////////////////////////////////////////////////////// 34 | @implementation BTBreadcrumbItem 35 | @synthesize title = _title; 36 | @end 37 | 38 | //////////////////////////////////////////////////////////////////////////////// 39 | //////////////////////////////////////////////////////////////////////////////// 40 | //////////////////////////////////////////////////////////////////////////////// 41 | @interface BTBreadcrumbView (Private) 42 | - (UIButton *)startButton; 43 | - (UIButton *)itemButton:(BTBreadcrumbItem *)item; 44 | - (void)didTapStartButton; 45 | - (void)didTapItemAtIndex:(NSUInteger)index; 46 | - (void)tapStartButton:(id)sender; 47 | - (void)tapItemButton:(id)sender; 48 | @end 49 | 50 | #define kStartButtonWidth 44 51 | #define kBreadcrumbHeight 44 52 | @implementation BTBreadcrumbView 53 | @synthesize items = _items; 54 | @synthesize delegate = _delegate; 55 | 56 | - (id)initWithFrame:(CGRect)frame 57 | { 58 | self = [super initWithFrame:frame]; 59 | if (self) { 60 | // Initialization code 61 | self.backgroundColor = [UIColor whiteColor]; 62 | self.autoresizesSubviews = YES; 63 | mSetShadow(self); 64 | 65 | _containerView = [[UIView alloc] initWithFrame:self.bounds]; 66 | _containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; 67 | _containerView.backgroundColor = [UIColor whiteColor]; 68 | _containerView.clipsToBounds = YES; 69 | [self addSubview:_containerView]; 70 | 71 | // Create fixed subviews 72 | _startButton = [self startButton]; 73 | [_containerView addSubview:_startButton]; 74 | } 75 | return self; 76 | } 77 | 78 | - (CGSize)sizeThatFits:(CGSize)size 79 | { 80 | CGFloat total_width = kStartButtonWidth; 81 | for (UIView *itemView in _itemViews) { 82 | total_width += itemView.bounds.size.width; 83 | } 84 | if (_itemViews.count > 0) 85 | { 86 | UIButton *lastButton = [_itemViews lastObject]; 87 | if (lastButton.titleEdgeInsets.right > 10) 88 | { 89 | total_width -= 12; 90 | } 91 | } 92 | return CGSizeMake(total_width, kBreadcrumbHeight); 93 | } 94 | 95 | #pragma mark Private 96 | - (UIButton *)startButton 97 | { 98 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 99 | button.contentMode = UIViewContentModeLeft; 100 | [button setBackgroundImage:[UIImage imageNamed:@"button_start.png"] forState:UIControlStateNormal]; 101 | button.frame = mRect(kStartButtonWidth+1, kBreadcrumbHeight); 102 | [button addTarget:self action:@selector(tapStartButton:) forControlEvents:UIControlEventTouchUpInside]; 103 | return button; 104 | } 105 | 106 | - (UIButton *)itemButton:(BTBreadcrumbItem *)item 107 | { 108 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 109 | button.contentMode = UIViewContentModeLeft; 110 | button.titleLabel.font = [UIFont boldSystemFontOfSize:16]; 111 | [button setTitle:item.title forState:UIControlStateNormal]; 112 | [button setTitleColor:mRGBA(77, 77, 77, 1) forState:UIControlStateNormal]; 113 | 114 | UIImage *bgImage = [[UIImage imageNamed:@"button_item.png"] stretchableImageWithLeftCapWidth:1 topCapHeight:0]; 115 | [button setBackgroundImage:bgImage forState:UIControlStateNormal]; 116 | [button setBackgroundImage:bgImage forState:UIControlStateHighlighted]; 117 | button.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 22); 118 | 119 | [button sizeToFit]; 120 | CGSize s = button.bounds.size; 121 | button.frame = CGRectMake(0, 0, s.width + 32, kBreadcrumbHeight); 122 | [button addTarget:self action:@selector(tapItemButton:) forControlEvents:UIControlEventTouchUpInside]; 123 | 124 | return button; 125 | } 126 | 127 | - (void)didTapStartButton 128 | { 129 | if (_delegate && [(id)_delegate respondsToSelector:@selector(breadcrumbViewDidTapStartButton:)]) 130 | { 131 | [_delegate breadcrumbViewDidTapStartButton:self]; 132 | } 133 | } 134 | - (void)didTapItemAtIndex:(NSUInteger)index 135 | { 136 | if (_delegate && [(id)_delegate respondsToSelector:@selector(breadcrumbView:didTapItemAtIndex:)]) 137 | { 138 | [_delegate breadcrumbView:self didTapItemAtIndex:index]; 139 | } 140 | } 141 | 142 | - (void)tapStartButton:(id)sender 143 | { 144 | [self didTapStartButton]; 145 | } 146 | - (void)tapItemButton:(id)sender 147 | { 148 | [self didTapItemAtIndex:[_itemViews indexOfObject:sender]]; 149 | } 150 | 151 | #pragma mark Layout 152 | - (void)layoutSubviews 153 | { 154 | [super layoutSubviews]; 155 | 156 | CGFloat cx = kStartButtonWidth; 157 | for (UIView *view in _itemViews) 158 | { 159 | CGSize s = view.bounds.size; 160 | view.frame = CGRectMake(cx, 0, s.width, s.height); 161 | cx += s.width; 162 | } 163 | } 164 | 165 | #pragma mark Public 166 | - (void)setItems:(NSArray *)items 167 | { 168 | if (_animating) return; 169 | 170 | // remove existings 171 | for (UIView *view in _itemViews) { 172 | [view removeFromSuperview]; 173 | } 174 | 175 | // add all 176 | _itemViews = [NSMutableArray arrayWithCapacity:0]; 177 | _items = items; 178 | int i = 0; 179 | for (BTBreadcrumbItem *item in _items) { 180 | UIButton *itemButton = [self itemButton:item]; 181 | [_containerView insertSubview:itemButton atIndex:0]; 182 | [_itemViews addObject:itemButton]; 183 | i++; 184 | } 185 | [self sizeToFit]; 186 | [self setNeedsLayout]; 187 | } 188 | 189 | - (void)updateButton:(UIButton *)button setLastItem:(BOOL)isLastItem 190 | { 191 | CGPoint o = button.frame.origin; 192 | CGSize s = button.frame.size; 193 | CGFloat w = s.width; 194 | if (isLastItem) 195 | { 196 | if (button.currentBackgroundImage != nil) 197 | { 198 | button.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10); 199 | [button setBackgroundImage:nil forState:UIControlStateNormal]; 200 | [button setBackgroundImage:nil forState:UIControlStateHighlighted]; 201 | button.backgroundColor = [UIColor whiteColor]; 202 | w = s.width-12; 203 | } 204 | } 205 | else 206 | { 207 | if (button.currentBackgroundImage == nil) 208 | { 209 | button.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 22); 210 | UIImage *bgImage = [[UIImage imageNamed:@"button_item.png"] stretchableImageWithLeftCapWidth:1 topCapHeight:0]; 211 | [button setBackgroundImage:bgImage forState:UIControlStateNormal]; 212 | [button setBackgroundImage:bgImage forState:UIControlStateHighlighted]; 213 | button.backgroundColor = [UIColor clearColor]; 214 | w = s.width+12; 215 | } 216 | } 217 | button.frame = CGRectMake(self.bounds.size.width-w, o.y, w, s.height); 218 | } 219 | 220 | - (void)setItems:(NSArray *)items animated:(BOOL)animated 221 | { 222 | if (_animating) return; 223 | 224 | if (animated) 225 | { 226 | // retract existings 227 | NSArray *oldItems = _items; 228 | _items = items; 229 | 230 | int oldCount = oldItems.count; 231 | int newCount = _items.count; 232 | 233 | int removeStartIndex = 0; 234 | for (int i = 0; i < oldCount; i++) 235 | { 236 | if (i < newCount) 237 | { 238 | BTBreadcrumbItem *oldItem = [oldItems objectAtIndex:i]; 239 | BTBreadcrumbItem *newItem = [_items objectAtIndex:i]; 240 | if (![newItem.title isEqual:oldItem.title]) 241 | { 242 | break; 243 | } 244 | } 245 | else 246 | { 247 | break; 248 | } 249 | removeStartIndex++; 250 | } 251 | 252 | NSArray *oldItemViews = _itemViews; 253 | _itemViews = [NSMutableArray arrayWithCapacity:0]; 254 | for (int i = 0; i < removeStartIndex; i++) 255 | { 256 | [_itemViews addObject:[oldItemViews objectAtIndex:i]]; 257 | } 258 | 259 | // retract first 260 | [UIView animateWithDuration:0.2 animations:^{ 261 | 262 | _animating = YES; 263 | 264 | [self sizeToFit]; 265 | 266 | // right bound 267 | for (int i = removeStartIndex; i < oldCount; i++) 268 | { 269 | UIButton *oldView = [oldItemViews objectAtIndex:i]; 270 | CGSize s = oldView.bounds.size; 271 | oldView.frame = CGRectMake(self.bounds.size.width-s.width, 0, s.width, s.height); 272 | } 273 | 274 | if (removeStartIndex < newCount) 275 | { 276 | if (removeStartIndex > 0) 277 | { 278 | UIButton *button = [_itemViews objectAtIndex:removeStartIndex-1]; 279 | [self updateButton:button setLastItem:NO]; 280 | } 281 | } 282 | 283 | [self sizeToFit]; 284 | 285 | } completion:^(BOOL finished) { 286 | 287 | for (int i = removeStartIndex; i < oldCount; i++) 288 | { 289 | UIView *oldView = [oldItemViews objectAtIndex:i]; 290 | [oldView removeFromSuperview]; 291 | } 292 | 293 | // adding new item 294 | if (removeStartIndex < newCount) 295 | { 296 | for (int i = removeStartIndex; i < newCount; i++) 297 | { 298 | BTBreadcrumbItem *item = [_items objectAtIndex:i]; 299 | UIView *newView = [self itemButton:item]; 300 | CGSize s = newView.bounds.size; 301 | newView.frame = CGRectMake(self.bounds.size.width-s.width, 0, s.width, s.height); 302 | [_containerView insertSubview:newView atIndex:0]; 303 | [_itemViews addObject:newView]; 304 | } 305 | if (newCount > 0) 306 | { 307 | UIButton *lastButton = [_itemViews objectAtIndex:newCount-1]; 308 | [self updateButton:lastButton setLastItem:YES]; 309 | } 310 | } 311 | 312 | // animate them 313 | [UIView animateWithDuration:0.2 animations:^{ 314 | [self sizeToFit]; 315 | [self layoutSubviews]; 316 | } completion:^(BOOL finished) { 317 | _animating = NO; 318 | }]; 319 | 320 | }]; 321 | 322 | } 323 | else 324 | { 325 | [self setItems:items]; 326 | } 327 | } 328 | @end 329 | 330 | -------------------------------------------------------------------------------- /Demo/BTAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // BTAppDelegate.h 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class BTViewController; 12 | 13 | @interface BTAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) BTViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Demo/BTAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // BTAppDelegate.m 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import "BTAppDelegate.h" 10 | 11 | #import "BTViewController.h" 12 | 13 | @implementation BTAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | // Override point for customization after application launch. 19 | self.viewController = [[BTViewController alloc] initWithNibName:@"BTViewController" bundle:nil]; 20 | self.window.rootViewController = self.viewController; 21 | [self.window makeKeyAndVisible]; 22 | return YES; 23 | } 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application 26 | { 27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 28 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 29 | } 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application 32 | { 33 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | - (void)applicationWillEnterForeground:(UIApplication *)application 38 | { 39 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 40 | } 41 | 42 | - (void)applicationDidBecomeActive:(UIApplication *)application 43 | { 44 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 45 | } 46 | 47 | - (void)applicationWillTerminate:(UIApplication *)application 48 | { 49 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Demo/BTBreadcumbView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.blockthirty.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations~ipad 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationPortraitUpsideDown 35 | UIInterfaceOrientationLandscapeLeft 36 | UIInterfaceOrientationLandscapeRight 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Demo/BTBreadcumbView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'BTFloatingMenu' target in the 'BTFloatingMenu' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Demo/BTViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BTViewController.h 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BTBreadcrumbView.h" 11 | 12 | @interface BTViewController : UIViewController 13 | { 14 | BTBreadcrumbView * _breadcrumb; 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /Demo/BTViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BTViewController.m 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import "BTViewController.h" 10 | 11 | #define mRGBA(_red,_green,_blue,_alpha) \ 12 | [UIColor colorWithRed:(_red/255.0) green:(_green/255.0) blue:(_blue/255.0) alpha:_alpha] 13 | 14 | @interface BTViewController () 15 | 16 | @end 17 | 18 | @implementation BTViewController 19 | 20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 21 | { 22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 23 | if (self) 24 | { 25 | 26 | } 27 | return self; 28 | } 29 | - (void)loadView 30 | { 31 | [super loadView]; 32 | self.view.backgroundColor = mRGBA(148, 248, 200, 1); 33 | 34 | _breadcrumb = [[BTBreadcrumbView alloc] initWithFrame:CGRectMake(20, 75, 0, 0)]; 35 | _breadcrumb.delegate = self; 36 | [_breadcrumb sizeToFit]; 37 | [self.view addSubview:_breadcrumb]; 38 | 39 | CGFloat cx = 20; 40 | CGFloat cy = 150; 41 | 42 | UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 43 | button1.tag = 1; 44 | [button1 setTitle:@"Level 1" forState:UIControlStateNormal]; 45 | [self.view addSubview:button1]; 46 | button1.frame = CGRectMake(cx, cy, 200, 30); 47 | cy += 40; 48 | [button1 addTarget:self action:@selector(updateBreadcrumb:) forControlEvents:UIControlEventTouchUpInside]; 49 | 50 | UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 51 | button2.tag = 2; 52 | [button2 setTitle:@"Level 1 > Level 2" forState:UIControlStateNormal]; 53 | [self.view addSubview:button2]; 54 | button2.frame = CGRectMake(cx, cy, 200, 30); 55 | cy += 40; 56 | [button2 addTarget:self action:@selector(updateBreadcrumb:) forControlEvents:UIControlEventTouchUpInside]; 57 | 58 | UIButton *button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 59 | button3.tag = 3; 60 | [button3 setTitle:@"Level 1 > Level 2 > Level 3" forState:UIControlStateNormal]; 61 | [self.view addSubview:button3]; 62 | button3.frame = CGRectMake(cx, cy, 200, 30); 63 | cy += 40; 64 | [button3 addTarget:self action:@selector(updateBreadcrumb:) forControlEvents:UIControlEventTouchUpInside]; 65 | 66 | UIButton *button4 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 67 | button4.tag = 4; 68 | [button4 setTitle:@"Thank You" forState:UIControlStateNormal]; 69 | [self.view addSubview:button4]; 70 | button4.frame = CGRectMake(cx, cy, 200, 30); 71 | cy += 40; 72 | [button4 addTarget:self action:@selector(updateBreadcrumb:) forControlEvents:UIControlEventTouchUpInside]; 73 | 74 | UIButton *button5 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 75 | button5.tag = 5; 76 | [button5 setTitle:@"" forState:UIControlStateNormal]; 77 | [self.view addSubview:button5]; 78 | button5.frame = CGRectMake(cx, cy, 200, 30); 79 | cy += 40; 80 | [button5 addTarget:self action:@selector(updateBreadcrumb:) forControlEvents:UIControlEventTouchUpInside]; 81 | } 82 | - (void)viewDidLoad 83 | { 84 | [super viewDidLoad]; 85 | } 86 | 87 | - (void)didReceiveMemoryWarning 88 | { 89 | [super didReceiveMemoryWarning]; 90 | // Dispose of any resources that can be recreated. 91 | } 92 | 93 | - (BTBreadcrumbItem *)item:(NSString *)title { 94 | // return [[BTFloatingMenuItem alloc] initWithTitle:title icon:nil]; 95 | BTBreadcrumbItem *item = [[BTBreadcrumbItem alloc] init]; 96 | item.title = title; 97 | return item; 98 | } 99 | - (void)updateBreadcrumb:(id)sender 100 | { 101 | UIButton *button = (UIButton *)sender; 102 | if (button.tag == 1) { // stakeholders 103 | [_breadcrumb setItems:[NSArray arrayWithObjects: 104 | [self item:@"Level 1"], nil] 105 | animated:YES]; 106 | } else if (button.tag == 2) { // stakeholders > general 107 | [_breadcrumb setItems:[NSArray arrayWithObjects: 108 | [self item:@"Level 1"], [self item:@"Level 2"], nil] 109 | animated:YES]; 110 | } else if (button.tag == 3) { // stakeholders > political 111 | [_breadcrumb setItems:[NSArray arrayWithObjects: 112 | [self item:@"Level 1"], [self item:@"Level 2"], [self item:@"Level 3"], nil] 113 | animated:YES]; 114 | } else if (button.tag == 4) { // home > project overview 115 | [_breadcrumb setItems:[NSArray arrayWithObjects: 116 | [self item:@"Thank You"], nil] 117 | animated:YES]; 118 | } else { 119 | [_breadcrumb setItems:[NSArray arrayWithObjects:nil] 120 | animated:YES]; 121 | } 122 | 123 | } 124 | 125 | - (void)breadcrumbViewDidTapStartButton:(BTBreadcrumbView *)view 126 | { 127 | NSLog(@"Start"); 128 | } 129 | - (void)breadcrumbView:(BTBreadcrumbView *)view didTapItemAtIndex:(NSUInteger)index 130 | { 131 | NSLog(@"Item at Index = %d", index); 132 | } 133 | @end 134 | -------------------------------------------------------------------------------- /Demo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Demo/Default-568h@2x.png -------------------------------------------------------------------------------- /Demo/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Demo/Default.png -------------------------------------------------------------------------------- /Demo/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Demo/Default@2x.png -------------------------------------------------------------------------------- /Demo/en.lproj/BTViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1536 5 | 12A206j 6 | 2519 7 | 1172.1 8 | 613.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1856 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBIPadFramework 28 | 29 | 30 | IBFirstResponder 31 | IBIPadFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {768, 1004}} 37 | 38 | 39 | 40 | 3 41 | MQA 42 | 43 | 2 44 | 45 | 46 | 47 | 2 48 | 49 | IBIPadFramework 50 | 51 | 52 | 53 | 54 | 55 | 56 | view 57 | 58 | 59 | 60 | 3 61 | 62 | 63 | 64 | 65 | 66 | 0 67 | 68 | 69 | 70 | 71 | 72 | -1 73 | 74 | 75 | File's Owner 76 | 77 | 78 | -2 79 | 80 | 81 | 82 | 83 | 2 84 | 85 | 86 | 87 | 88 | 89 | 90 | BTViewController 91 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 92 | UIResponder 93 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 94 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 95 | 96 | 97 | 98 | 99 | 100 | 3 101 | 102 | 103 | 104 | 105 | BTViewController 106 | UIViewController 107 | 108 | IBProjectSource 109 | ./Classes/BTViewController.h 110 | 111 | 112 | 113 | 114 | 0 115 | IBIPadFramework 116 | YES 117 | 3 118 | YES 119 | 1856 120 | 121 | 122 | -------------------------------------------------------------------------------- /Demo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BTFloatingMenu 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "BTAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([BTAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BTBreadcrumbView 2 | 3 | ## Overview 4 | 5 | __this is work in progress__ 6 | 7 | ![Screenshot](https://raw.github.com/meiwin/BTBreadcrumbView/master/screenshot.png) 8 | 9 | Watch quick demo in [youtube](http://www.youtube.com/watch?v=UQSrwGeOJ0U&feature=youtu.be "BTBreadcrumbView Demo") 10 | 11 | A breadcrumb ios control, features: 12 | 13 | - Simple API 14 | - Animated transition 15 | 16 | ## Roadmap 17 | 18 | - UI appearance customization 19 | - Configure max allowed width to expand 20 | - Auto retract when idle 21 | 22 | ## Licensing 23 | 24 | BTBreadcrumbView is licensed under MIT License 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: 25 | 26 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 27 | 28 | 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. 29 | -------------------------------------------------------------------------------- /Resources/breadcrumb_design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/breadcrumb_design.png -------------------------------------------------------------------------------- /Resources/breadcrumb_design.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/breadcrumb_design.psd -------------------------------------------------------------------------------- /Resources/breadcrumb_design@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/breadcrumb_design@2x.png -------------------------------------------------------------------------------- /Resources/button_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_item.png -------------------------------------------------------------------------------- /Resources/button_item.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_item.psd -------------------------------------------------------------------------------- /Resources/button_item@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_item@2x.png -------------------------------------------------------------------------------- /Resources/button_item@2x.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_item@2x.psd -------------------------------------------------------------------------------- /Resources/button_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_start.png -------------------------------------------------------------------------------- /Resources/button_start.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_start.psd -------------------------------------------------------------------------------- /Resources/button_start@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_start@2x.png -------------------------------------------------------------------------------- /Resources/button_start@2x.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/Resources/button_start@2x.psd -------------------------------------------------------------------------------- /Tests/BTFloatingMenuTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.blockthirty.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/BTFloatingMenuTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // BTFloatingMenuTests.h 3 | // BTFloatingMenuTests 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BTFloatingMenuTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Tests/BTFloatingMenuTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BTFloatingMenuTests.m 3 | // BTFloatingMenuTests 4 | // 5 | // Created by Meiwin Fu on 12/1/13. 6 | // Copyright (c) 2013 BlockThirty. All rights reserved. 7 | // 8 | 9 | #import "BTFloatingMenuTests.h" 10 | 11 | @implementation BTFloatingMenuTests 12 | 13 | - (void)setUp 14 | { 15 | [super setUp]; 16 | 17 | // Set-up code here. 18 | } 19 | 20 | - (void)tearDown 21 | { 22 | // Tear-down code here. 23 | 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample 28 | { 29 | STFail(@"Unit tests are not implemented yet in BTFloatingMenuTests"); 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meiwin/BTBreadcrumbView/c80b98316a014033cdf62a224105dbe0367b4ddc/screenshot.png --------------------------------------------------------------------------------