├── BMTNavigationBar ├── BMTNavigationBar.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── huangjinhua.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── huangjinhua.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── BMTNavigationBar.xcscheme │ │ └── xcschememanagement.plist └── BMTNavigationBar │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Classes │ ├── BMNavigationBar.h │ ├── BMNavigationBar.m │ ├── BMNavigationBarHeader.h │ ├── BMUtils.h │ ├── BMUtils.m │ ├── UINavigationBar+BMExtend.h │ ├── UINavigationBar+BMExtend.m │ ├── UINavigationController+Extend.h │ ├── UINavigationController+Extend.m │ ├── UIView+ExtendRegion.h │ └── UIView+ExtendRegion.m │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── LICENSE └── README.md /BMTNavigationBar/BMTNavigationBar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9E2CE88C1F5A4FB700830DC8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E2CE88B1F5A4FB700830DC8 /* main.m */; }; 11 | 9E2CE88F1F5A4FB700830DC8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E2CE88E1F5A4FB700830DC8 /* AppDelegate.m */; }; 12 | 9E2CE8921F5A4FB700830DC8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E2CE8911F5A4FB700830DC8 /* ViewController.m */; }; 13 | 9E2CE8951F5A4FB700830DC8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9E2CE8931F5A4FB700830DC8 /* Main.storyboard */; }; 14 | 9E2CE8971F5A4FB700830DC8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9E2CE8961F5A4FB700830DC8 /* Assets.xcassets */; }; 15 | 9E2CE89A1F5A4FB700830DC8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9E2CE8981F5A4FB700830DC8 /* LaunchScreen.storyboard */; }; 16 | 9E5F1C17202C328100D9FFEB /* BMUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C16202C328100D9FFEB /* BMUtils.m */; }; 17 | 9E5F1C1A202C32BD00D9FFEB /* UINavigationController+Extend.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C19202C32BD00D9FFEB /* UINavigationController+Extend.m */; }; 18 | 9E5F1C1D202C394F00D9FFEB /* UINavigationBar+BMExtend.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C1C202C394F00D9FFEB /* UINavigationBar+BMExtend.m */; }; 19 | 9E5F1C4D202C4DEF00D9FFEB /* ZGBarButtonTitle.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E5F1C3C202C4DEF00D9FFEB /* ZGBarButtonTitle.strings */; }; 20 | 9E5F1C4E202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C3E202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.m */; }; 21 | 9E5F1C4F202C4DEF00D9FFEB /* NSObject+ZGRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C43202C4DEF00D9FFEB /* NSObject+ZGRuntime.m */; }; 22 | 9E5F1C50202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C45202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.m */; }; 23 | 9E5F1C51202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C47202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.m */; }; 24 | 9E5F1C52202C4DEF00D9FFEB /* ZGBarButtonIcons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9E5F1C48202C4DEF00D9FFEB /* ZGBarButtonIcons.xcassets */; }; 25 | 9E5F1C53202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E5F1C4A202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.m */; }; 26 | 9E5F1C54202C4DEF00D9FFEB /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 9E5F1C4B202C4DEF00D9FFEB /* LICENSE */; }; 27 | 9E5F1C55202C4DEF00D9FFEB /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 9E5F1C4C202C4DEF00D9FFEB /* README.md */; }; 28 | 9ED07ACE1FD4E808007223BA /* UIView+ExtendRegion.m in Sources */ = {isa = PBXBuildFile; fileRef = 9ED07ACB1FD4E808007223BA /* UIView+ExtendRegion.m */; }; 29 | 9ED07ACF1FD4E808007223BA /* BMNavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 9ED07ACC1FD4E808007223BA /* BMNavigationBar.m */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 9E2CE8871F5A4FB700830DC8 /* BMTNavigationBar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BMTNavigationBar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 9E2CE88B1F5A4FB700830DC8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | 9E2CE88D1F5A4FB700830DC8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | 9E2CE88E1F5A4FB700830DC8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | 9E2CE8901F5A4FB700830DC8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 38 | 9E2CE8911F5A4FB700830DC8 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 39 | 9E2CE8941F5A4FB700830DC8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 40 | 9E2CE8961F5A4FB700830DC8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 41 | 9E2CE8991F5A4FB700830DC8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 42 | 9E2CE89B1F5A4FB700830DC8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | 9E5F1C15202C328100D9FFEB /* BMUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BMUtils.h; sourceTree = ""; }; 44 | 9E5F1C16202C328100D9FFEB /* BMUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BMUtils.m; sourceTree = ""; }; 45 | 9E5F1C18202C32BD00D9FFEB /* UINavigationController+Extend.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UINavigationController+Extend.h"; sourceTree = ""; }; 46 | 9E5F1C19202C32BD00D9FFEB /* UINavigationController+Extend.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+Extend.m"; sourceTree = ""; }; 47 | 9E5F1C1B202C394F00D9FFEB /* UINavigationBar+BMExtend.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UINavigationBar+BMExtend.h"; sourceTree = ""; }; 48 | 9E5F1C1C202C394F00D9FFEB /* UINavigationBar+BMExtend.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UINavigationBar+BMExtend.m"; sourceTree = ""; }; 49 | 9E5F1C3D202C4DEF00D9FFEB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/ZGBarButtonTitle.strings"; sourceTree = ""; }; 50 | 9E5F1C3E202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+ZGFixSpace.m"; sourceTree = ""; }; 51 | 9E5F1C3F202C4DEF00D9FFEB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ZGBarButtonTitle.strings; sourceTree = ""; }; 52 | 9E5F1C40202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ZGLayoutConstraint.h"; sourceTree = ""; }; 53 | 9E5F1C41202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationItem+ZGFixSpace.h"; sourceTree = ""; }; 54 | 9E5F1C42202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZGBarButtonItemCustomView.h; sourceTree = ""; }; 55 | 9E5F1C43202C4DEF00D9FFEB /* NSObject+ZGRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+ZGRuntime.m"; sourceTree = ""; }; 56 | 9E5F1C44202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+ZGFixSpace.h"; sourceTree = ""; }; 57 | 9E5F1C45202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ZGLayoutConstraint.m"; sourceTree = ""; }; 58 | 9E5F1C46202C4DEF00D9FFEB /* ZGNavBarItemSpceMacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZGNavBarItemSpceMacro.h; sourceTree = ""; }; 59 | 9E5F1C47202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationItem+ZGFixSpace.m"; sourceTree = ""; }; 60 | 9E5F1C48202C4DEF00D9FFEB /* ZGBarButtonIcons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ZGBarButtonIcons.xcassets; sourceTree = ""; }; 61 | 9E5F1C49202C4DEF00D9FFEB /* NSObject+ZGRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+ZGRuntime.h"; sourceTree = ""; }; 62 | 9E5F1C4A202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZGBarButtonItemCustomView.m; sourceTree = ""; }; 63 | 9E5F1C4B202C4DEF00D9FFEB /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 64 | 9E5F1C4C202C4DEF00D9FFEB /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 65 | 9ED07AC91FD4E808007223BA /* BMNavigationBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMNavigationBar.h; sourceTree = ""; }; 66 | 9ED07ACA1FD4E808007223BA /* BMNavigationBarHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMNavigationBarHeader.h; sourceTree = ""; }; 67 | 9ED07ACB1FD4E808007223BA /* UIView+ExtendRegion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ExtendRegion.m"; sourceTree = ""; }; 68 | 9ED07ACC1FD4E808007223BA /* BMNavigationBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BMNavigationBar.m; sourceTree = ""; }; 69 | 9ED07ACD1FD4E808007223BA /* UIView+ExtendRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ExtendRegion.h"; sourceTree = ""; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | 9E2CE8841F5A4FB700830DC8 /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | /* End PBXFrameworksBuildPhase section */ 81 | 82 | /* Begin PBXGroup section */ 83 | 9E2CE87E1F5A4FB700830DC8 = { 84 | isa = PBXGroup; 85 | children = ( 86 | 9E2CE8891F5A4FB700830DC8 /* BMTNavigationBar */, 87 | 9E2CE8881F5A4FB700830DC8 /* Products */, 88 | ); 89 | sourceTree = ""; 90 | }; 91 | 9E2CE8881F5A4FB700830DC8 /* Products */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 9E2CE8871F5A4FB700830DC8 /* BMTNavigationBar.app */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 9E2CE8891F5A4FB700830DC8 /* BMTNavigationBar */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 9E5F1C3A202C4DEF00D9FFEB /* ZGNavigationBarItemFixSpace-master */, 103 | 9ED07AC81FD4E808007223BA /* Classes */, 104 | 9E2CE88D1F5A4FB700830DC8 /* AppDelegate.h */, 105 | 9E2CE88E1F5A4FB700830DC8 /* AppDelegate.m */, 106 | 9E2CE8901F5A4FB700830DC8 /* ViewController.h */, 107 | 9E2CE8911F5A4FB700830DC8 /* ViewController.m */, 108 | 9E2CE8931F5A4FB700830DC8 /* Main.storyboard */, 109 | 9E2CE8961F5A4FB700830DC8 /* Assets.xcassets */, 110 | 9E2CE8981F5A4FB700830DC8 /* LaunchScreen.storyboard */, 111 | 9E2CE89B1F5A4FB700830DC8 /* Info.plist */, 112 | 9E2CE88A1F5A4FB700830DC8 /* Supporting Files */, 113 | ); 114 | path = BMTNavigationBar; 115 | sourceTree = ""; 116 | }; 117 | 9E2CE88A1F5A4FB700830DC8 /* Supporting Files */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 9E2CE88B1F5A4FB700830DC8 /* main.m */, 121 | ); 122 | name = "Supporting Files"; 123 | sourceTree = ""; 124 | }; 125 | 9E5F1C3A202C4DEF00D9FFEB /* ZGNavigationBarItemFixSpace-master */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 9E5F1C3B202C4DEF00D9FFEB /* ZGNavigationBarItemFixSpace */, 129 | 9E5F1C4B202C4DEF00D9FFEB /* LICENSE */, 130 | 9E5F1C4C202C4DEF00D9FFEB /* README.md */, 131 | ); 132 | name = "ZGNavigationBarItemFixSpace-master"; 133 | path = "../../../../../../../../Desktop/ZGNavigationBarItemFixSpace-master"; 134 | sourceTree = ""; 135 | }; 136 | 9E5F1C3B202C4DEF00D9FFEB /* ZGNavigationBarItemFixSpace */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 9E5F1C3C202C4DEF00D9FFEB /* ZGBarButtonTitle.strings */, 140 | 9E5F1C3E202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.m */, 141 | 9E5F1C40202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.h */, 142 | 9E5F1C41202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.h */, 143 | 9E5F1C42202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.h */, 144 | 9E5F1C43202C4DEF00D9FFEB /* NSObject+ZGRuntime.m */, 145 | 9E5F1C44202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.h */, 146 | 9E5F1C45202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.m */, 147 | 9E5F1C46202C4DEF00D9FFEB /* ZGNavBarItemSpceMacro.h */, 148 | 9E5F1C47202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.m */, 149 | 9E5F1C48202C4DEF00D9FFEB /* ZGBarButtonIcons.xcassets */, 150 | 9E5F1C49202C4DEF00D9FFEB /* NSObject+ZGRuntime.h */, 151 | 9E5F1C4A202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.m */, 152 | ); 153 | path = ZGNavigationBarItemFixSpace; 154 | sourceTree = ""; 155 | }; 156 | 9ED07AC81FD4E808007223BA /* Classes */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 9ED07ACA1FD4E808007223BA /* BMNavigationBarHeader.h */, 160 | 9ED07AC91FD4E808007223BA /* BMNavigationBar.h */, 161 | 9ED07ACC1FD4E808007223BA /* BMNavigationBar.m */, 162 | 9ED07ACD1FD4E808007223BA /* UIView+ExtendRegion.h */, 163 | 9ED07ACB1FD4E808007223BA /* UIView+ExtendRegion.m */, 164 | 9E5F1C15202C328100D9FFEB /* BMUtils.h */, 165 | 9E5F1C16202C328100D9FFEB /* BMUtils.m */, 166 | 9E5F1C18202C32BD00D9FFEB /* UINavigationController+Extend.h */, 167 | 9E5F1C19202C32BD00D9FFEB /* UINavigationController+Extend.m */, 168 | 9E5F1C1B202C394F00D9FFEB /* UINavigationBar+BMExtend.h */, 169 | 9E5F1C1C202C394F00D9FFEB /* UINavigationBar+BMExtend.m */, 170 | ); 171 | path = Classes; 172 | sourceTree = ""; 173 | }; 174 | /* End PBXGroup section */ 175 | 176 | /* Begin PBXNativeTarget section */ 177 | 9E2CE8861F5A4FB700830DC8 /* BMTNavigationBar */ = { 178 | isa = PBXNativeTarget; 179 | buildConfigurationList = 9E2CE89E1F5A4FB700830DC8 /* Build configuration list for PBXNativeTarget "BMTNavigationBar" */; 180 | buildPhases = ( 181 | 9E2CE8831F5A4FB700830DC8 /* Sources */, 182 | 9E2CE8841F5A4FB700830DC8 /* Frameworks */, 183 | 9E2CE8851F5A4FB700830DC8 /* Resources */, 184 | ); 185 | buildRules = ( 186 | ); 187 | dependencies = ( 188 | ); 189 | name = BMTNavigationBar; 190 | productName = BMTNavigationBar; 191 | productReference = 9E2CE8871F5A4FB700830DC8 /* BMTNavigationBar.app */; 192 | productType = "com.apple.product-type.application"; 193 | }; 194 | /* End PBXNativeTarget section */ 195 | 196 | /* Begin PBXProject section */ 197 | 9E2CE87F1F5A4FB700830DC8 /* Project object */ = { 198 | isa = PBXProject; 199 | attributes = { 200 | LastUpgradeCheck = 0900; 201 | ORGANIZATIONNAME = BMu; 202 | TargetAttributes = { 203 | 9E2CE8861F5A4FB700830DC8 = { 204 | CreatedOnToolsVersion = 8.3.3; 205 | ProvisioningStyle = Automatic; 206 | }; 207 | }; 208 | }; 209 | buildConfigurationList = 9E2CE8821F5A4FB700830DC8 /* Build configuration list for PBXProject "BMTNavigationBar" */; 210 | compatibilityVersion = "Xcode 3.2"; 211 | developmentRegion = English; 212 | hasScannedForEncodings = 0; 213 | knownRegions = ( 214 | en, 215 | Base, 216 | "zh-Hans", 217 | ); 218 | mainGroup = 9E2CE87E1F5A4FB700830DC8; 219 | productRefGroup = 9E2CE8881F5A4FB700830DC8 /* Products */; 220 | projectDirPath = ""; 221 | projectRoot = ""; 222 | targets = ( 223 | 9E2CE8861F5A4FB700830DC8 /* BMTNavigationBar */, 224 | ); 225 | }; 226 | /* End PBXProject section */ 227 | 228 | /* Begin PBXResourcesBuildPhase section */ 229 | 9E2CE8851F5A4FB700830DC8 /* Resources */ = { 230 | isa = PBXResourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | 9E5F1C54202C4DEF00D9FFEB /* LICENSE in Resources */, 234 | 9E5F1C4D202C4DEF00D9FFEB /* ZGBarButtonTitle.strings in Resources */, 235 | 9E2CE89A1F5A4FB700830DC8 /* LaunchScreen.storyboard in Resources */, 236 | 9E5F1C55202C4DEF00D9FFEB /* README.md in Resources */, 237 | 9E2CE8971F5A4FB700830DC8 /* Assets.xcassets in Resources */, 238 | 9E2CE8951F5A4FB700830DC8 /* Main.storyboard in Resources */, 239 | 9E5F1C52202C4DEF00D9FFEB /* ZGBarButtonIcons.xcassets in Resources */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | /* End PBXResourcesBuildPhase section */ 244 | 245 | /* Begin PBXSourcesBuildPhase section */ 246 | 9E2CE8831F5A4FB700830DC8 /* Sources */ = { 247 | isa = PBXSourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | 9E5F1C51202C4DEF00D9FFEB /* UINavigationItem+ZGFixSpace.m in Sources */, 251 | 9ED07ACE1FD4E808007223BA /* UIView+ExtendRegion.m in Sources */, 252 | 9E2CE8921F5A4FB700830DC8 /* ViewController.m in Sources */, 253 | 9E5F1C1D202C394F00D9FFEB /* UINavigationBar+BMExtend.m in Sources */, 254 | 9E5F1C4F202C4DEF00D9FFEB /* NSObject+ZGRuntime.m in Sources */, 255 | 9E2CE88F1F5A4FB700830DC8 /* AppDelegate.m in Sources */, 256 | 9E5F1C4E202C4DEF00D9FFEB /* UIBarButtonItem+ZGFixSpace.m in Sources */, 257 | 9E5F1C1A202C32BD00D9FFEB /* UINavigationController+Extend.m in Sources */, 258 | 9E2CE88C1F5A4FB700830DC8 /* main.m in Sources */, 259 | 9E5F1C17202C328100D9FFEB /* BMUtils.m in Sources */, 260 | 9E5F1C50202C4DEF00D9FFEB /* UIView+ZGLayoutConstraint.m in Sources */, 261 | 9E5F1C53202C4DEF00D9FFEB /* ZGBarButtonItemCustomView.m in Sources */, 262 | 9ED07ACF1FD4E808007223BA /* BMNavigationBar.m in Sources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXSourcesBuildPhase section */ 267 | 268 | /* Begin PBXVariantGroup section */ 269 | 9E2CE8931F5A4FB700830DC8 /* Main.storyboard */ = { 270 | isa = PBXVariantGroup; 271 | children = ( 272 | 9E2CE8941F5A4FB700830DC8 /* Base */, 273 | ); 274 | name = Main.storyboard; 275 | sourceTree = ""; 276 | }; 277 | 9E2CE8981F5A4FB700830DC8 /* LaunchScreen.storyboard */ = { 278 | isa = PBXVariantGroup; 279 | children = ( 280 | 9E2CE8991F5A4FB700830DC8 /* Base */, 281 | ); 282 | name = LaunchScreen.storyboard; 283 | sourceTree = ""; 284 | }; 285 | 9E5F1C3C202C4DEF00D9FFEB /* ZGBarButtonTitle.strings */ = { 286 | isa = PBXVariantGroup; 287 | children = ( 288 | 9E5F1C3D202C4DEF00D9FFEB /* zh-Hans */, 289 | 9E5F1C3F202C4DEF00D9FFEB /* en */, 290 | ); 291 | name = ZGBarButtonTitle.strings; 292 | sourceTree = ""; 293 | }; 294 | /* End PBXVariantGroup section */ 295 | 296 | /* Begin XCBuildConfiguration section */ 297 | 9E2CE89C1F5A4FB700830DC8 /* Debug */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | ALWAYS_SEARCH_USER_PATHS = NO; 301 | CLANG_ANALYZER_NONNULL = YES; 302 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 303 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 304 | CLANG_CXX_LIBRARY = "libc++"; 305 | CLANG_ENABLE_MODULES = YES; 306 | CLANG_ENABLE_OBJC_ARC = YES; 307 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 308 | CLANG_WARN_BOOL_CONVERSION = YES; 309 | CLANG_WARN_COMMA = YES; 310 | CLANG_WARN_CONSTANT_CONVERSION = YES; 311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 312 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 313 | CLANG_WARN_EMPTY_BODY = YES; 314 | CLANG_WARN_ENUM_CONVERSION = YES; 315 | CLANG_WARN_INFINITE_RECURSION = YES; 316 | CLANG_WARN_INT_CONVERSION = YES; 317 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 318 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 320 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 321 | CLANG_WARN_STRICT_PROTOTYPES = YES; 322 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 323 | CLANG_WARN_UNREACHABLE_CODE = YES; 324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 326 | COPY_PHASE_STRIP = NO; 327 | DEBUG_INFORMATION_FORMAT = dwarf; 328 | ENABLE_STRICT_OBJC_MSGSEND = YES; 329 | ENABLE_TESTABILITY = YES; 330 | GCC_C_LANGUAGE_STANDARD = gnu99; 331 | GCC_DYNAMIC_NO_PIC = NO; 332 | GCC_NO_COMMON_BLOCKS = YES; 333 | GCC_OPTIMIZATION_LEVEL = 0; 334 | GCC_PREPROCESSOR_DEFINITIONS = ( 335 | "DEBUG=1", 336 | "$(inherited)", 337 | ); 338 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 339 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 340 | GCC_WARN_UNDECLARED_SELECTOR = YES; 341 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 342 | GCC_WARN_UNUSED_FUNCTION = YES; 343 | GCC_WARN_UNUSED_VARIABLE = YES; 344 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 345 | MTL_ENABLE_DEBUG_INFO = YES; 346 | ONLY_ACTIVE_ARCH = YES; 347 | SDKROOT = iphoneos; 348 | }; 349 | name = Debug; 350 | }; 351 | 9E2CE89D1F5A4FB700830DC8 /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ALWAYS_SEARCH_USER_PATHS = NO; 355 | CLANG_ANALYZER_NONNULL = YES; 356 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 357 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 358 | CLANG_CXX_LIBRARY = "libc++"; 359 | CLANG_ENABLE_MODULES = YES; 360 | CLANG_ENABLE_OBJC_ARC = YES; 361 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 362 | CLANG_WARN_BOOL_CONVERSION = YES; 363 | CLANG_WARN_COMMA = YES; 364 | CLANG_WARN_CONSTANT_CONVERSION = YES; 365 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 366 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 367 | CLANG_WARN_EMPTY_BODY = YES; 368 | CLANG_WARN_ENUM_CONVERSION = YES; 369 | CLANG_WARN_INFINITE_RECURSION = YES; 370 | CLANG_WARN_INT_CONVERSION = YES; 371 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 372 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 373 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 374 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 375 | CLANG_WARN_STRICT_PROTOTYPES = YES; 376 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 377 | CLANG_WARN_UNREACHABLE_CODE = YES; 378 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 379 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 380 | COPY_PHASE_STRIP = NO; 381 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 382 | ENABLE_NS_ASSERTIONS = NO; 383 | ENABLE_STRICT_OBJC_MSGSEND = YES; 384 | GCC_C_LANGUAGE_STANDARD = gnu99; 385 | GCC_NO_COMMON_BLOCKS = YES; 386 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 387 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 388 | GCC_WARN_UNDECLARED_SELECTOR = YES; 389 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 390 | GCC_WARN_UNUSED_FUNCTION = YES; 391 | GCC_WARN_UNUSED_VARIABLE = YES; 392 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 393 | MTL_ENABLE_DEBUG_INFO = NO; 394 | SDKROOT = iphoneos; 395 | VALIDATE_PRODUCT = YES; 396 | }; 397 | name = Release; 398 | }; 399 | 9E2CE89F1F5A4FB700830DC8 /* Debug */ = { 400 | isa = XCBuildConfiguration; 401 | buildSettings = { 402 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 403 | DEVELOPMENT_TEAM = ""; 404 | INFOPLIST_FILE = BMTNavigationBar/Info.plist; 405 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 406 | PRODUCT_BUNDLE_IDENTIFIER = com.bmu.BMTNavigationBar; 407 | PRODUCT_NAME = "$(TARGET_NAME)"; 408 | }; 409 | name = Debug; 410 | }; 411 | 9E2CE8A01F5A4FB700830DC8 /* Release */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 415 | DEVELOPMENT_TEAM = ""; 416 | INFOPLIST_FILE = BMTNavigationBar/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.bmu.BMTNavigationBar; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | }; 421 | name = Release; 422 | }; 423 | /* End XCBuildConfiguration section */ 424 | 425 | /* Begin XCConfigurationList section */ 426 | 9E2CE8821F5A4FB700830DC8 /* Build configuration list for PBXProject "BMTNavigationBar" */ = { 427 | isa = XCConfigurationList; 428 | buildConfigurations = ( 429 | 9E2CE89C1F5A4FB700830DC8 /* Debug */, 430 | 9E2CE89D1F5A4FB700830DC8 /* Release */, 431 | ); 432 | defaultConfigurationIsVisible = 0; 433 | defaultConfigurationName = Release; 434 | }; 435 | 9E2CE89E1F5A4FB700830DC8 /* Build configuration list for PBXNativeTarget "BMTNavigationBar" */ = { 436 | isa = XCConfigurationList; 437 | buildConfigurations = ( 438 | 9E2CE89F1F5A4FB700830DC8 /* Debug */, 439 | 9E2CE8A01F5A4FB700830DC8 /* Release */, 440 | ); 441 | defaultConfigurationIsVisible = 0; 442 | defaultConfigurationName = Release; 443 | }; 444 | /* End XCConfigurationList section */ 445 | }; 446 | rootObject = 9E2CE87F1F5A4FB700830DC8 /* Project object */; 447 | } 448 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar.xcodeproj/project.xcworkspace/xcuserdata/huangjinhua.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/BMTNavigationBar/e2eba1478172d86df9a470bdeaf42a301a762637/BMTNavigationBar/BMTNavigationBar.xcodeproj/project.xcworkspace/xcuserdata/huangjinhua.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar.xcodeproj/xcuserdata/huangjinhua.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar.xcodeproj/xcuserdata/huangjinhua.xcuserdatad/xcschemes/BMTNavigationBar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar.xcodeproj/xcuserdata/huangjinhua.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BMTNavigationBar.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9E2CE8861F5A4FB700830DC8 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/BMNavigationBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMNavigationBar.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/11/6. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_OPTIONS(NSUInteger, ButtonType) { 12 | LeftButtonType = 1, 13 | RightButtonType = 1 << 1 14 | }; 15 | 16 | @interface BMNavigationBar : UIView 17 | 18 | @property (nonatomic, assign) ButtonType buttonType; 19 | @property (nonatomic, copy) void(^clickLeftButtonBlock)(UIButton *button); 20 | @property (nonatomic, copy) void(^clickRightButtonBlock)(UIButton *button); 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/BMNavigationBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMNavigationBar.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/11/6. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import "BMNavigationBar.h" 10 | #import "BMNavigationBarHeader.h" 11 | #import "UIView+ExtendRegion.h" 12 | 13 | @interface BMNavigationBar() 14 | 15 | @property (nonatomic, strong) UIButton *leftButton; 16 | @property (nonatomic, strong) UIButton *rightButton; 17 | 18 | @end 19 | 20 | @implementation BMNavigationBar 21 | 22 | - (instancetype)init { 23 | self = [super initWithFrame: CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width - NavigationBarTitleViewMargin * 2, 44)]; 24 | if (self) { 25 | self.extendRegionType = ExtendClickedRegion; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)willMoveToSuperview:(UIView *)newSuperview { 31 | [super willMoveToSuperview: newSuperview]; 32 | if (newSuperview) { 33 | if (self.buttonType & LeftButtonType && !self.leftButton.superview) { 34 | self.leftButton = [UIButton buttonWithType: UIButtonTypeCustom]; 35 | self.leftButton.backgroundColor = [UIColor blueColor]; 36 | self.leftButton.frame = CGRectMake(- NavigationBarTitleViewMargin, 0, 60, 44);; 37 | self.leftButton.tag = 0; 38 | [self.leftButton addTarget: self action: @selector(handleLeftButtonEvent:) forControlEvents: UIControlEventTouchUpInside]; 39 | [self addSubview: self.leftButton]; 40 | } 41 | if (self.buttonType & RightButtonType && !self.rightButton.superview) { 42 | self.rightButton = [UIButton buttonWithType: UIButtonTypeCustom]; 43 | self.rightButton.backgroundColor = [UIColor blueColor]; 44 | self.rightButton.frame = CGRectMake(self.frame.size.width + NavigationBarTitleViewMargin - 60, 0, 60, 44); 45 | self.rightButton.tag = 1; 46 | [self.rightButton addTarget: self action: @selector(handleRightButtonEvent:) forControlEvents: UIControlEventTouchUpInside]; 47 | [self addSubview: self.rightButton]; 48 | } 49 | } 50 | } 51 | 52 | - (void)handleLeftButtonEvent: (UIButton *)button { 53 | if (self.clickLeftButtonBlock) { 54 | self.clickLeftButtonBlock(button); 55 | } 56 | } 57 | 58 | - (void)handleRightButtonEvent: (UIButton *)button { 59 | if (self.clickRightButtonBlock) { 60 | self.clickRightButtonBlock(button); 61 | } 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/BMNavigationBarHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMNavigationBarHeader.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #ifndef BMNavigationBarHeader_h 10 | #define BMNavigationBarHeader_h 11 | 12 | #define isIOS11 ([[UIDevice currentDevice].systemVersion floatValue] >= 11) 13 | 14 | /** 15 | 导航栏titleView尽可能充满屏幕,余留的边距 16 | iPhone5s/iPhone6(iOS8/iOS9/iOS10) margin = 8 17 | iPhone6p(iOS8/iOS9/iOS10) margin = 12 18 | 19 | iPhone5s/iPhone6(iOS11) margin = 16 20 | iPhone6p(iOS11) margin = 20 21 | */ 22 | #define NavigationBarTitleViewMargin \ 23 | (isIOS11? ([UIScreen mainScreen].bounds.size.width > 375 ? 20 : 16) : \ 24 | ([UIScreen mainScreen].bounds.size.width > 375 ? 12 : 8)) 25 | 26 | /** 27 | 导航栏左右navigationBarItem余留的边距 28 | iPhone5s/iPhone6(iOS8/iOS9/iOS10) margin = 16 29 | iPhone6p(iOS8/iOS9/iOS10) margin = 20 30 | */ 31 | #define NavigationBarItemMargin ([UIScreen mainScreen].bounds.size.width > 375 ? 20 : 16) 32 | 33 | /** 34 | 导航栏titleView和navigationBarItem之间的间距 35 | iPhone5s/iPhone6/iPhone6p(iOS8/iOS9/iOS10) iterItemSpace = 6 36 | */ 37 | #define NavigationBarInterItemSpace 6 38 | 39 | #define BM_ScreenWidth [UIScreen mainScreen].bounds.size.width 40 | #define BM_ScreenHeight [UIScreen mainScreen].bounds.size.height 41 | 42 | #define BM_NavigationBarHeight 44 43 | 44 | #endif /* BMNavigationBarHeader_h */ 45 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/BMUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMUtils.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 08/02/2018. 6 | // Copyright © 2018 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMUtils : NSObject 12 | 13 | /** 14 | 实例方法交换 15 | 16 | @param cls 交换方法的类 17 | @param originalSelector 原始方法 18 | @param swizzledSelector 交换方法 19 | */ 20 | extern void swizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector); 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/BMUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMUtils.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 08/02/2018. 6 | // Copyright © 2018 BMu. All rights reserved. 7 | // 8 | 9 | #import "BMUtils.h" 10 | #import 11 | 12 | @implementation BMUtils 13 | 14 | void swizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector){ 15 | Method originalMethod = class_getInstanceMethod(cls, originalSelector); 16 | Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector); 17 | 18 | BOOL didAddMethod = class_addMethod(cls, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); 19 | if (didAddMethod) { 20 | class_replaceMethod(cls, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 21 | } else { 22 | method_exchangeImplementations(originalMethod, swizzledMethod); 23 | } 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/UINavigationBar+BMExtend.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+BMExtend.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 08/02/2018. 6 | // Copyright © 2018 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationBar (BMExtend) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/UINavigationBar+BMExtend.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+BMExtend.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 08/02/2018. 6 | // Copyright © 2018 BMu. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBar+BMExtend.h" 10 | #import "BMUtils.h" 11 | #import "BMNavigationBarHeader.h" 12 | 13 | @implementation UINavigationBar (BMExtend) 14 | 15 | + (void)load { 16 | swizzleInstanceMethod([self class], @selector(layoutSubviews), @selector(bm_layoutSubviews)); 17 | } 18 | 19 | - (void)bm_layoutSubviews { 20 | if (isIOS11 && self.subviews.count) { 21 | for (UIView *subView in self.subviews) { 22 | if ([subView isKindOfClass: NSClassFromString(@"_UINavigationBarContentView")]) { 23 | for (UIView *subView2 in subView.subviews) { 24 | if ([subView2 isKindOfClass: NSClassFromString(@"_UITAMICAdaptorView")]) { 25 | } 26 | if ([subView2 isKindOfClass: NSClassFromString(@"_UIButtonBarStackView")]) { 27 | NSArray *constrains = subView2.constraints; 28 | NSLog(@"%@", constrains); 29 | } 30 | } 31 | } 32 | } 33 | } 34 | [self bm_layoutSubviews]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/UINavigationController+Extend.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+Extend.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 08/02/2018. 6 | // Copyright © 2018 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationController (Extend) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/UINavigationController+Extend.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+Extend.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 08/02/2018. 6 | // Copyright © 2018 BMu. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+Extend.h" 10 | #import "BMUtils.h" 11 | 12 | @implementation UINavigationController (Extend) 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/UIView+ExtendRegion.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+ExtendRegion.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, ExtendRegionType) { 12 | DefaultExtendRegion = 0, 13 | ExtendClickedRegion = 1 14 | }; 15 | 16 | @interface UIView (ExtendRegion) 17 | 18 | @property (nonatomic, assign) ExtendRegionType extendRegionType; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Classes/UIView+ExtendRegion.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+ExtendRegion.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import "UIView+ExtendRegion.h" 10 | #import "BMNavigationBarHeader.h" 11 | #import 12 | 13 | @implementation UIView (ExtendRegion) 14 | 15 | #pragma mark - Ovrride methods 16 | + (void)load { 17 | Method originalMethod = class_getInstanceMethod([self class], @selector(hitTest:withEvent:)); 18 | Method swizzleMethod = class_getInstanceMethod([self class], @selector(bm_hitTest:withEvent:)); 19 | 20 | BOOL didAddMethod = class_addMethod([self class], @selector(bm_hitTest:withEvent:), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 21 | if (didAddMethod) { 22 | class_replaceMethod([self class], @selector(hitTest:withEvent:), method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod)); 23 | } else { 24 | method_exchangeImplementations(originalMethod, swizzleMethod); 25 | } 26 | } 27 | 28 | - (UIView *)bm_hitTest:(CGPoint)point withEvent:(UIEvent *)event { 29 | UIView *hitView = [self bm_hitTest: point withEvent: event]; 30 | if (hitView) { 31 | return hitView; 32 | } 33 | if (!hitView) { 34 | if (self.extendRegionType == ExtendClickedRegion) { 35 | //普通类型扩展 36 | for (UIView *subView in self.subviews) { 37 | CGPoint newPoint = [subView convertPoint: point fromView: self]; 38 | if (CGRectContainsPoint(subView.bounds, newPoint)) { 39 | hitView = subView; 40 | } 41 | } 42 | } 43 | if ([NSStringFromClass([self class]) isEqualToString: @"_UITAMICAdaptorView"]) { 44 | //iOS11 导航栏的_UITAMICAdaptorView类 45 | for (UIView *subview in self.subviews) { 46 | if (subview.subviews > 0) { 47 | for (UIView *item in subview.subviews) { 48 | CGPoint newPoint = [item convertPoint: point fromView: self]; 49 | if (CGRectContainsPoint(item.bounds, newPoint)) { 50 | hitView = item; 51 | } 52 | } 53 | } 54 | } 55 | } 56 | } 57 | return hitView; 58 | } 59 | 60 | #pragma mark - Custome methods 61 | - (ExtendRegionType)extendRegionType { 62 | return [objc_getAssociatedObject([self class], @selector(extendRegionType)) unsignedIntegerValue]; 63 | } 64 | 65 | - (void)setExtendRegionType:(ExtendRegionType)extendRegionType { 66 | objc_setAssociatedObject([self class], @selector(extendRegionType), @(extendRegionType), OBJC_ASSOCIATION_ASSIGN); 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "BMNavigationBar.h" 11 | #import "BMNavigationBarHeader.h" 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | // UIView *bmBar = [[UIView alloc] initWithFrame: CGRectMake(0, 0, BM_ScreenWidth, BM_NavigationBarHeight)]; 23 | // bmBar.backgroundColor = [UIColor blueColor]; 24 | // self.navigationItem.titleView = bmBar; 25 | 26 | UIButton *leftBtn = [UIButton buttonWithType: UIButtonTypeCustom]; 27 | leftBtn.backgroundColor = [UIColor yellowColor]; 28 | leftBtn.frame = CGRectMake(0, 0, 44, 44); 29 | UIButton *leftBtn2 = [UIButton buttonWithType: UIButtonTypeCustom]; 30 | leftBtn2.backgroundColor = [UIColor greenColor]; 31 | leftBtn2.frame = CGRectMake(0, 0, 44, 44); 32 | 33 | UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView: leftBtn]; 34 | UIBarButtonItem *leftItem2 = [[UIBarButtonItem alloc] initWithCustomView: leftBtn2]; 35 | self.navigationItem.leftBarButtonItems = @[leftItem, leftItem2]; 36 | 37 | UIButton *rightBtn = [UIButton buttonWithType: UIButtonTypeCustom]; 38 | rightBtn.backgroundColor = [UIColor orangeColor]; 39 | rightBtn.frame = CGRectMake(0, 0, 44, 44); 40 | UIButton *rightBtn2 = [UIButton buttonWithType: UIButtonTypeCustom]; 41 | rightBtn2.backgroundColor = [UIColor purpleColor]; 42 | rightBtn2.frame = CGRectMake(0, 0, 44, 44); 43 | 44 | UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView: rightBtn]; 45 | UIBarButtonItem *rightItem2 = [[UIBarButtonItem alloc] initWithCustomView: rightBtn2]; 46 | // self.navigationItem.rightBarButtonItems = @[rightItem, rightItem2]; 47 | // BMNavigationBar *bmBar = [BMNavigationBar new]; 48 | // bmBar.buttonType = LeftButtonType | RightButtonType; 49 | // bmBar.clickLeftButtonBlock = ^(UIButton *button){ 50 | // NSLog(@"点击了左按钮"); 51 | // }; 52 | // bmBar.clickRightButtonBlock = ^(UIButton *button){ 53 | // NSLog(@"点击了右按钮"); 54 | // }; 55 | // self.navigationItem.titleView = bmBar; 56 | } 57 | 58 | - (void)viewWillAppear:(BOOL)animated { 59 | [super viewWillAppear: animated]; 60 | 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /BMTNavigationBar/BMTNavigationBar/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BMTNavigationBar 4 | // 5 | // Created by Jashion on 2017/9/2. 6 | // Copyright © 2017年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 JinHua Huang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BMTNavigationBar 2 | 解决导航栏titleView不充满全屏的问题,并适配iOS11。 3 | 4 | >公司的App是居于iOS8以上的,页面显示在iOS8~iOS10都没有问题,但是,iOS11beta版显示出现各种问题,真是顾客虐你千百遍,你待顾客如初恋,苹果搞事,我们也只能暗暗的承受。😜 5 | 6 | ### 搞事一:导航栏 7 | #### 1.导航栏高度变化 8 | 导航栏在iOS10之前都是默认的64p,但是,到了iOS10就不单单是64p了,可以看一下系统的信息App,在iOS11添加了大标题,效果如下图1: 9 | ![图1.png](http://upload-images.jianshu.io/upload_images/968977-410f670afe737036.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 10 | 11 | navigationBar的结构,看图2、3、4: 12 | ![图2.png](http://upload-images.jianshu.io/upload_images/968977-d8b3b973da772f58.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | ![图3.png](http://upload-images.jianshu.io/upload_images/968977-eda62ec78c92a749.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 15 | 16 | ![图4.png](http://upload-images.jianshu.io/upload_images/968977-1ccd0e3e986513a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 17 | 18 | 在上面三幅图可以知道,在iOS11导航栏多了一个LargeTitleView,专门显示大字标题用的,整个导航栏的高度达到了96p,这不包括状态栏的高度,也就是说,整个app顶部高度达到了116p,其中statusbar=20,title=44,largetitle=52,不过默认是64p;当然,**iPhoneX**的高度会更高点,如果不显示大字标题,顶部的高度也达到了88,statusbar=44,title=44,如果显示大字标题,则高度变成了140,statusbar=44,title=44,largetitle=52,也就是说,**iPhoneX**的刘海高度为24p,大字标题如下图: 19 | 20 | ![iPhoneX之前的机型.png](http://upload-images.jianshu.io/upload_images/968977-89a88f618da51832.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 21 | 22 | ![iPhoneX.png](http://upload-images.jianshu.io/upload_images/968977-b19a09df0a51bf50.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 23 | 24 | #### 2.导航栏的图层变化 25 | iOS11之前导航栏的title是添加在UINavigationItemView上面,而navigationBarButton则直接添加在navigationBar上面;如果设置了titleView,则titleView也是直接添加在navigationBar上面,如图5: 26 | 27 | ![图5.png](http://upload-images.jianshu.io/upload_images/968977-c6fe6299a9fedd8b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 28 | 29 | 30 | 在iOS11之后,苹果添加了新的类来管理,navigationBar会添加在_UIButtonBarStackView上面,而_UIButtonBarStackView则添加在_UINavigationBarContentView上面;如果没有给titleView赋值,则titleView会直接添加在_UINavigationBarContentView上面,如果赋值给了titleView,则会新生成_UITAMICAdaptorView,把titleView添加在这个类上面,这个类会添加在_UINavigationBarContentView上面,如下图6、7: 31 | 32 | ![图6.png](http://upload-images.jianshu.io/upload_images/968977-9ce6865faee333d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 33 | 34 | ![图7.png](http://upload-images.jianshu.io/upload_images/968977-4d38220d0a6bc66a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 35 | 36 | #### 3.导航栏的边距变化 37 | 在iOS11对导航栏里面的item的边距也做了调整: 38 | ###### (1)如果只是设置了titleView,没有设置barbutton,把titleview的宽度设置为屏幕宽度,则titleview距离屏幕的边距,iOS11之前,在iPhone6p上是20p,在iPhone6p之前是16p;iOS11之后,在iPhone6p上是12p,在iPhone6p之前是8p。 39 | ###### (2)如果只是设置了barbutton,没有设置titleview,则在iOS11里,barButton距离屏幕的边距是20p和16p;在iOS11之前,barButton距离屏幕的边距也是20p和16p。 40 | ###### (3)如果同时设置了titleView和barButton,则在iOS11之前,titleview和barbutton之间的间距是6p,在iOS11上titleview和barbutton之间无间距,如下图8、9: 41 | 42 | ![图8.png](http://upload-images.jianshu.io/upload_images/968977-f3ace14e6195da4f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 43 | 44 | ![图9.png](http://upload-images.jianshu.io/upload_images/968977-32b1d97a39d15160.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 45 | 46 | #### 4.App需要实现导航栏左右按钮边距为0 47 | 在iOS11之前,可以设置一个width为负的navigationBarButton,将按钮挤到边缘,变相实现0边距的导航栏按钮,但是,这招在iOS11失效了,原因在于_UIButtonBarStackView,这个iOS9之后出来的,用来相对布局的组件,限制了子view的布局。那怎么搞呢? 48 | 49 | **想到的方法有几个:** 50 | (1)在viewWillAppear里面,将_UIButtonBarStackView取出来,直接设置它的x坐标。 51 | (2)设置titleView,然后将button添加在titleView上面,根据不同的边距做偏移。 52 | 53 | 方法一: 54 | 遇到的问题,在viewDidLoad,viewWillAppear,viewWillLayoutSubviews,viewDidLayoutSubviews里面都取不到_UIButtonBarStackView,只有在viewDidAppear里才能取到值,这样就会在页面显示了之后才开始移动navigationBarButton,显然这样体验不好,所以,暂时pass掉。 55 | 56 | 方法二: 57 | 这个做法完全可以做到0边距,但是,问题来了,就是点击区域的问题。因为左右navigationBarButton的点击区域是超出父view的,所以,点击不到。这好办,重写titleView的hitTest方法就好。嘿嘿嘿,问题没有那么简单。之前在iOS11的图层结构就解释过,titleView会被添加在_UITAMICAdaptorView上面,而重点是,这个view也有边距,所以,单单重写titleView的hitTest方法还不够,那怎么解决呢?我的办法就是写一个view的类别,hook所有view的hitTest方法,在里面判断是否是iOS11以上,是否是_UITAMICAdaptorView类,如果都满足条件,则可以搞事了。😜[Demo](https://github.com/jashion/BMTNavigationBar/tree/master) 58 | ### 搞事二:列表的变化 59 | #### 1.automaticallyAdjustsScrollViewInsets 60 | 在iOS11之前,如果想要scrollView不偏移64p,则需设置automaticallyAdjustsScrollViewInsets=NO,但是这个属性在iOS11直接被遗弃了😳: 61 | ``` 62 | @property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets 63 | API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); 64 | ``` 65 | 所以,看一下contentInsetAdjustmentBehavior是何方神圣: 66 | ``` 67 | typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) { 68 | UIScrollViewContentInsetAdjustmentAutomatic, // Similar to .scrollableAxes, but will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewContentInset = YES inside a navigation controller, regardless of whether the scroll view is scrollable 69 | UIScrollViewContentInsetAdjustmentScrollableAxes, // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES) 70 | UIScrollViewContentInsetAdjustmentNever, // contentInset is not adjusted 71 | UIScrollViewContentInsetAdjustmentAlways, // contentInset is always adjusted by the scroll view's safeAreaInsets 72 | } API_AVAILABLE(ios(11.0),tvos(11.0)); 73 | 74 | /* Configure the behavior of adjustedContentInset. 75 | Default is UIScrollViewContentInsetAdjustmentAutomatic. 76 | */ 77 | @property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE(ios(11.0),tvos(11.0)); 78 | ``` 79 | 看起来这和iOS11搞的safeArea有关,这个先放一遍,看看怎么适配: 80 | ``` 81 | #define adjustsScrollViewInsets_NO(scrollView,vc)\ 82 | do { \ 83 | _Pragma("clang diagnostic push") \ 84 | _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ 85 | if ([UIScrollView instancesRespondToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\ 86 | [scrollView performSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:") withObject:@(2)];\ 87 | } else {\ 88 | vc.automaticallyAdjustsScrollViewInsets = NO;\ 89 | }\ 90 | _Pragma("clang diagnostic pop") \ 91 | } while (0) 92 | ``` 93 | 上面是公司里面一个大神写的,这样就可以在Xcode8上面跑了。 94 | #### 2.tableView默认使用Self-Sizing 95 | 这个配合estimatedRowHeight、estimatedSectionFooterHeight、estimatedSectionHeaderHeight使用,可以预估高度。之前,设置header或者footer高度为0时,需要设置height=0.1,才会起作用,如果直接设置为0,则会使用默认高度。iOS11由于自动使用预估高度,所以,忽略了设置的高度,使原来的高度增大了。只要把这几个属性设置为0就可以解决。 96 | 97 | ### 搞事三:iPhoneX底部tabbar的高度改变 98 | iPhoneX不止多了刘海,底部还有一个半角的矩形,使得tabbar多出来了34p的高度,不过不管导航栏和tabbar一般系统都会自动适配safeArea。 99 | 100 | ![iPhoneX tabbar.png](http://upload-images.jianshu.io/upload_images/968977-be7d00e5fded4863.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 101 | 102 | ### 搞事四:iOS11 iPhoneX页面push时tabbar位置变化 103 | 直接上图: 104 | ![iOS11 iPhoneX Tabbar.gif](http://upload-images.jianshu.io/upload_images/968977-1f1703830fef106d.gif?imageMogr2/auto-orient/strip) 105 | 106 | 可以看到在页面push的时候,tabbar的frame上移了,这个只有在iPhoneX上面才能看到(因为iPhoneX的TabBar的高度不一样),有可能是模拟器的bug,但是,具体要到真机出来才知道。下面说说修复的几种办法: 107 | ###### (1)将导航栏的代理设置为当前的controller,然后在将要展示下个页面的方法里修正TabBar的frame。 108 | ``` 109 | - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 110 | if (![[[UIDevice currentDevice] modelName] isEqualToString: @"iPhone X"]) { 111 | return; 112 | } 113 | CGRect frame = self.tabBarController.tabBar.frame; 114 | if (frame.origin.y < ([UIScreen mainScreen].bounds.size.height - 83)) { 115 | frame.origin.y = [UIScreen mainScreen].bounds.size.height - 83; 116 | self.tabBarController.tabBar.frame = frame; 117 | } 118 | } 119 | ``` 120 | ###### (2)新建一个类,继承UITabBar,然后在setFrame:里面做判断修正,将改类替换系统默认的TabBar。 121 | ``` 122 | - (void)setFrame:(CGRect)frame { 123 | if ([[[UIDevice currentDevice] modelName] isEqualToString: @"iPhone X"]) { 124 | if (frame.origin.y < ([UIScreen mainScreen].bounds.size.height - 83)) { 125 | frame.origin.y = [UIScreen mainScreen].bounds.size.height - 83; 126 | } 127 | } 128 | [super setFrame: frame]; 129 | } 130 | ``` 131 | ###### (3)其他方法。 132 | 133 | ### 总结: 134 | iOS11系统改变还是比较大的,某些地方需要注意适配,不然会出现很奇怪的现象。暂时,在iOS11遇到这么多坑,以后遇到会继续分享的。 135 | 136 | 137 | ### 参考: 138 | [你可能需要为你的 APP 适配 iOS 11](http://www.10tiao.com/html/330/201707/2653579210/1.html) 139 | --------------------------------------------------------------------------------