Xcode 15设置自定义UINavigationBar导致App崩溃求助
解决方案
1. 子类化UINavigationController指定自定义导航栏类
苹果在iOS 17/Xcode 15中收紧了对KVC修改navigationBar私有属性的限制,直接替换实例会触发布局断言。推荐通过子类化导航控制器的方式让系统自动创建自定义导航栏:
@interface CustomNavigationController : UINavigationController @end @implementation CustomNavigationController + (Class)navigationBarClass { return [NavigationBar class]; } @end
之后在项目中使用CustomNavigationController替代系统的UINavigationController即可,无需手动替换导航栏实例。
2. 改用Method Swizzling或直接添加子视图实现自定义
如果无法替换导航控制器,可通过方法交换扩展系统导航栏的功能,或直接在原有导航栏上添加自定义子视图:
方法交换示例
@implementation UINavigationBar (Customization) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ SEL originalSel = @selector(layoutSubviews); SEL swizzledSel = @selector(custom_layoutSubviews); Method originalMethod = class_getInstanceMethod(self, originalSel); Method swizzledMethod = class_getInstanceMethod(self, swizzledSel); BOOL added = class_addMethod(self, originalSel, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (added) { class_replaceMethod(self, swizzledSel, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } - (void)custom_layoutSubviews { [self custom_layoutSubviews]; // 调用原系统布局逻辑 // 添加你的自定义布局或功能代码 } @end
添加自定义子视图示例
// 在控制器的viewDidLoad中执行 UIView *customBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.navigationController.navigationBar.frame.size.height)]; // 配置customBarView的样式、按钮等元素 [self.navigationController.navigationBar addSubview:customBarView];
3. 检查自定义NavigationBar的布局逻辑
如果坚持使用自定义导航栏类,确保layoutSubviews方法中先调用父类的布局方法,避免破坏系统布局流程:
@implementation NavigationBar - (void)layoutSubviews { [super layoutSubviews]; // 必须优先执行系统布局 // 你的自定义布局代码 } @end
内容的提问来源于stack exchange,提问作者Surbhit Thanvi
相关产品推荐
相关产品推荐

