UINavigationItem+GKExtension.swift
6.3 KB
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//
// UINavigationItem+GKExtension.swift
// GKNavigationBarSwift
//
// Created by QuintGao on 2020/3/25.
// Copyright © 2020 QuintGao. All rights reserved.
//
import UIKit
extension UINavigationItem: GKAwakeProtocol {
// MARK: - 重新系统方法
private static let onceToken = UUID().uuidString
@objc public static func gkAwake() {
DispatchQueue.once(token: onceToken) {
if #available(iOS 11.0, *) {} else {
let oriSels = ["setLeftBarButtonItem:animated:",
"setLeftBarButtonItems:animated:",
"setRightBarButtonItem:animated:",
"setRightBarButtonItems:animated:"]
for oriSel in oriSels {
gk_swizzled_instanceMethod("gk", oldClass: self, oldSelector: oriSel, newClass: self)
}
}
}
}
@objc func gk_setLeftBarButtonItem(_ item: UIBarButtonItem?, animated: Bool) {
if !GKConfigure.fixNavItemSpaceDisabled() && item != nil { // 存在按钮且需要调节
self.setLeftBarButtonItems([item!], animated: animated)
}else { // 不存在按钮或者不需要调节
self.setLeftBarButtonItems(nil, animated: false)
self.gk_setLeftBarButtonItem(item, animated: animated)
}
}
@objc func gk_setLeftBarButtonItems(_ items: [UIBarButtonItem]?, animated: Bool) {
guard var leftItems = items else { return }
if !GKConfigure.fixNavItemSpaceDisabled() && leftItems.count > 0 {
let firstItem = leftItems.first!
let width = GKConfigure.gk_navItemLeftSpace - GKConfigure.gk_fixedSpace()
if firstItem.width == width {
self.gk_setLeftBarButtonItems(leftItems, animated: animated)
}else {
leftItems.insert(fixedSpace(width), at: 0)
self.gk_setLeftBarButtonItems(leftItems, animated: animated)
}
}else {
self.gk_setLeftBarButtonItems(leftItems, animated: animated)
}
}
@objc func gk_setRightBarButtonItem(_ item: UIBarButtonItem?, animated: Bool) {
if !GKConfigure.fixNavItemSpaceDisabled() && item != nil {
self.setRightBarButtonItems([item!], animated: animated)
}else {
self.setRightBarButtonItems(nil, animated: false)
self.gk_setRightBarButtonItem(item, animated: animated)
}
}
@objc func gk_setRightBarButtonItems(_ items: [UIBarButtonItem]?, animated: Bool) {
guard var rightItems = items else { return }
if !GKConfigure.fixNavItemSpaceDisabled() && rightItems.count > 0 {
let firstItem = rightItems.first!
let width = GKConfigure.gk_navItemRightSpace - GKConfigure.gk_fixedSpace()
if firstItem.width == width {
self.gk_setRightBarButtonItems(items, animated: animated)
}else {
rightItems.insert(fixedSpace(width), at: 0)
self.gk_setRightBarButtonItems(rightItems, animated: animated)
}
}else {
self.gk_setRightBarButtonItems(rightItems, animated: animated);
}
}
fileprivate func fixedSpace(_ width: CGFloat) -> UIBarButtonItem {
let fixedItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
fixedItem.width = width
return fixedItem
}
}
extension NSObject: GKObjectAwakeProtocol {
// MARK: - 重新系统方法
private static let onceToken = UUID().uuidString
public static func gkObjectAwake() {
DispatchQueue.once(token: onceToken) {
if #available(iOS 11.0, *) {
let oriSels = ["_UINavigationBarContentView": "layoutSubviews", "_UINavigationBarContentViewLayout": "_updateMarginConstraints"]
for (cls, sel) in oriSels {
gk_swizzled_instanceMethod("gk", oldClass: NSClassFromString(cls), oldSelector: sel, newClass: NSObject.self)
}
}
}
}
@objc func gk_layoutSubviews() {
gk_layoutSubviews()
if GKConfigure.fixNavItemSpaceDisabled() { return }
if let cls = NSClassFromString("_UINavigationBarContentView") {
if !self.isMember(of: cls) { return }
guard let layout = self.value(forKey: "_layout") as? NSObject else { return }
let selector = NSSelectorFromString("_updateMarginConstraints")
if layout.responds(to: selector) {
layout.perform(selector)
}
}
}
@objc func gk__updateMarginConstraints() {
gk__updateMarginConstraints()
if GKConfigure.fixNavItemSpaceDisabled() { return }
if let cls = NSClassFromString("_UINavigationBarContentViewLayout") {
if !self.isMember(of: cls) { return }
gk_adjustLeadingBarConstraints()
gk_adjustTrailingBarConstraints()
}
}
fileprivate func gk_adjustLeadingBarConstraints() {
if GKConfigure.fixNavItemSpaceDisabled() { return }
let leadingBarConstrainst: [NSLayoutConstraint]? = self.value(forKey: "_leadingBarConstraints") as? [NSLayoutConstraint]
if leadingBarConstrainst == nil { return }
let constant = GKConfigure.gk_navItemLeftSpace - GKConfigure.gk_fixedSpace()
for constraint in leadingBarConstrainst! {
if constraint.firstAttribute == .leading && constraint.secondAttribute == .leading {
constraint.constant = constant
}
}
}
fileprivate func gk_adjustTrailingBarConstraints() {
if GKConfigure.fixNavItemSpaceDisabled() { return }
let trailingBarConstraints: [NSLayoutConstraint]? = self.value(forKey: "_trailingBarConstraints") as? [NSLayoutConstraint]
if trailingBarConstraints == nil { return }
let constant = GKConfigure.gk_fixedSpace() - GKConfigure.gk_navItemRightSpace
for constraint in trailingBarConstraints! {
if constraint.firstAttribute == .trailing && constraint.secondAttribute == .trailing {
constraint.constant = constant
}
}
}
}