iOS 13 以上修改导航栏左边距

iOS 导航栏上的返回按钮是有左边距的,有时需根据设计需要修改这个左边距,下面分析将左边距设为 0 的方法

左边距为 0

在 iOS10 及以下可以设置一个宽度为负的UIBarButtonItem

UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSpacer.width = -16;
self.navigationItem.leftBarButtonItems = @[negativeSpacer,  customItem];

在 iOS11 以上,将 width 设为负不再起效,需要自定义UINavigationBar

class InsetButtonsNavigationBar: UINavigationBar {
    override func layoutSubviews() {
        super.layoutSubviews()
            for view in subviews {
                if NSStringFromClass(type(of: view.self)).contains("ContentView") {
                    view.layoutMargins = .zero
                    break
                }
            }
    }
}

但到了 iOS13,系统不再允许修改 private view 的 layoutMargins,上面的代码会报错

Client error attempting to change layout margins of a private view

此时需要修改 UINavigationBarContentView 的 frame

class InsetButtonsNavigationBar: UINavigationBar {
    override func layoutSubviews() {
        super.layoutSubviews()

        if #available(iOS 13.0, *) {
            for view in subviews {
                if "\(view.self)".contains("_UINavigationBarContentView") {
                    let margins = view.layoutMargins
                    view.frame = CGRect(x: -margins.left, y: view.y, width: view.width  + margins.left + margins.right, height: view.height)
                    break
                }
            }
        } else {
            for view in subviews {
                if "\(view.self)".contains("ContentView") {
                    view.layoutMargins = .zero
                    break
                }
            }
        }
    }
}

使用方式

let nav = UINavigationController(navigationBarClass: InsetButtonsNavigationBar.self, toolbarClass: UIToolbar.self)
nav.viewControllers = [ViewController()]
window.rootViewController = nav
window.makeKeyAndVisible()

注意这种方式修改了UINavigationBarContentView 的 frame,使其超出了屏幕

修改 UINavigationBarContentView 的 frame

你可能感兴趣的:(iOS 13 以上修改导航栏左边距)