iOS26适配之UIBarButtonItem

490 阅读2分钟

iOS26 UINavigationBar 导航栏返回按钮, 被系统默认加了 Liquid glass 效果, 个人认为这个效果并不好看, 主要是为了保证App整体风格 和 减少工作量,所以需要去掉这个所谓的液态玻璃效果.经过一下午的研究,终于找到一个最简单直接的方法.就是直接将 UIBarButtonItem 的属性 hidesSharedBackground 设置为 YES, 就神奇般的被隐藏了.

液态玻璃效果

image.png

修改属性 hidesSharedBackground

UIButton *btn = [[UIButton alloc] init];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn];
if (@available(iOS 26.0, *)) {
    item.hidesSharedBackground = YES;
}

隐藏效果 - 恢复

image.png

黑魔法全局禁用

创建一个分类UIBarButtonItem, 在分类中用OC黑魔法方法交换,自动禁用液态玻璃效果.如分类名称为 DefaultHideBackground.

  • 头文件UIBarButtonItem+DefaultHideBackground.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIBarButtonItem (DefaultHideBackground)

@end

NS_ASSUME_NONNULL_END

  • 实现文件UIBarButtonItem+DefaultHideBackground.m

#import "UIBarButtonItem+DefaultHideBackground.h"
#import <objc/runtime.h>

@implementation UIBarButtonItem (DefaultHideBackground)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        
        // 需要交换的初始化方法列表
        SEL selectors[] = {
            @selector(initWithTitle:style:target:action:),
            @selector(initWithImage:style:target:action:),
            @selector(initWithBarButtonSystemItem:target:action:),
            @selector(initWithCustomView:),
            @selector(initWithCoder:), // 处理从 Interface Builder 创建
            @selector(init)             // 处理直接使用 init 的情况
        };
        
        for (NSUInteger i = 0; i < sizeof(selectors) / sizeof(SEL); i++) {
            SEL originalSelector = selectors[i];
            NSString *swizzledName = [@"swizzled_" stringByAppendingString:NSStringFromSelector(originalSelector)];
            SEL swizzledSelector = NSSelectorFromString(swizzledName);
            
            Method originalMethod = class_getInstanceMethod(class, originalSelector);
            Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
            
            if (originalMethod && swizzledMethod) {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            } else {
                NSLog(@"Failed to swizzle method: %@", NSStringFromSelector(originalSelector));
            }
        }
    });
}

#pragma mark - Swizzled Initializers

- (instancetype)swizzled_initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action {
    UIBarButtonItem *item = [self swizzled_initWithTitle:title style:style target:target action:action]; // 实际调用原方法
    [item applyDefaultHidesSharedBackground];
    return item;
}

- (instancetype)swizzled_initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action {
    UIBarButtonItem *item = [self swizzled_initWithImage:image style:style target:target action:action];
    [item applyDefaultHidesSharedBackground];
    return item;
}

- (instancetype)swizzled_initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action {
    UIBarButtonItem *item = [self swizzled_initWithBarButtonSystemItem:systemItem target:target action:action];
    [item applyDefaultHidesSharedBackground];
    return item;
}

- (instancetype)swizzled_initWithCustomView:(UIView *)customView {
    UIBarButtonItem *item = [self swizzled_initWithCustomView:customView];
    [item applyDefaultHidesSharedBackground];
    return item;
}

- (instancetype)swizzled_initWithCoder:(NSCoder *)coder {
    UIBarButtonItem *item = [self swizzled_initWithCoder:coder];
    [item applyDefaultHidesSharedBackground];
    return item;
}

- (instancetype)swizzled_init {
    UIBarButtonItem *item = [self swizzled_init];
    [item applyDefaultHidesSharedBackground];
    return item;
}

#pragma mark - Helper Method

- (void)applyDefaultHidesSharedBackground {
    if (@available(iOS 26.0, *)) {
        self.hidesSharedBackground = YES;
    }
}

@end