优化导航栏 push 和 pop 动画效果

FFIB vor 6 Jahren
Ursprung
Commit
2cde165abd

BIN
PaiAi/.DS_Store


+ 5 - 1
PaiAi/Paiai.xcodeproj/project.pbxproj

@@ -181,6 +181,7 @@
181 181
 		0543E80F21D1FD1100A42807 /* GroupDetailItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0543E80E21D1FD1100A42807 /* GroupDetailItem.swift */; };
182 182
 		0546D9852242460700742939 /* OriginData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0546D9842242460700742939 /* OriginData.swift */; };
183 183
 		054B6C45223F884600939FE6 /* PhotoDetailRemoteAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 054B6C44223F884600939FE6 /* PhotoDetailRemoteAPI.swift */; };
184
+		054D8398228288FD0074561A /* NavigationBarConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 054D8397228288FD0074561A /* NavigationBarConfiguration.swift */; };
184 185
 		05594BFF2240BEDE002D4910 /* PhotoDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05594BFE2240BEDE002D4910 /* PhotoDetailViewModel.swift */; };
185 186
 		05594C012240BF9C002D4910 /* PhotoPurchaseViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05594C002240BF9C002D4910 /* PhotoPurchaseViewModel.swift */; };
186 187
 		05594C032240E94E002D4910 /* PhotoDetailImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05594C022240E94E002D4910 /* PhotoDetailImageCell.swift */; };
@@ -436,6 +437,7 @@
436 437
 		054863661FA326CB00A39DA0 /* PhotoCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoCell.swift; sourceTree = "<group>"; };
437 438
 		054863671FA326CB00A39DA0 /* PhotoCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PhotoCell.xib; sourceTree = "<group>"; };
438 439
 		054B6C44223F884600939FE6 /* PhotoDetailRemoteAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoDetailRemoteAPI.swift; sourceTree = "<group>"; };
440
+		054D8397228288FD0074561A /* NavigationBarConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarConfiguration.swift; sourceTree = "<group>"; };
439 441
 		05594BFE2240BEDE002D4910 /* PhotoDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoDetailViewModel.swift; sourceTree = "<group>"; };
440 442
 		05594C002240BF9C002D4910 /* PhotoPurchaseViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPurchaseViewModel.swift; sourceTree = "<group>"; };
441 443
 		05594C022240E94E002D4910 /* PhotoDetailImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoDetailImageCell.swift; sourceTree = "<group>"; };
@@ -642,6 +644,7 @@
642 644
 			children = (
643 645
 				05AF61BE226EFAF700AD8E2F /* NavigationBar.swift */,
644 646
 				05EE558A226F070B00E13460 /* NavigationController.swift */,
647
+				054D8397228288FD0074561A /* NavigationBarConfiguration.swift */,
645 648
 			);
646 649
 			path = NavigationController;
647 650
 			sourceTree = "<group>";
@@ -1595,7 +1598,7 @@
1595 1598
 			);
1596 1599
 			runOnlyForDeploymentPostprocessing = 0;
1597 1600
 			shellPath = /bin/sh;
1598
-			shellScript = "/usr/local/bin/carthage copy-frameworks\nif which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
1601
+			shellScript = "/usr/local/bin/carthage copy-frameworks\n";
1599 1602
 		};
1600 1603
 /* End PBXShellScriptBuildPhase section */
1601 1604
 
@@ -1652,6 +1655,7 @@
1652 1655
 				05130F5A21C94C12004EF1BE /* PresentDisappearAnimatedTransitioning.swift in Sources */,
1653 1656
 				053E126721F1719F00A64893 /* PageItem.swift in Sources */,
1654 1657
 				053E127821F5B6E400A64893 /* AlertController.swift in Sources */,
1658
+				054D8398228288FD0074561A /* NavigationBarConfiguration.swift in Sources */,
1655 1659
 				05C5285621FE98F50090ECB5 /* GestureRecognizerProxy.swift in Sources */,
1656 1660
 				05130F5921C94C12004EF1BE /* AlertViewController.swift in Sources */,
1657 1661
 				05EE558B226F070B00E13460 /* NavigationController.swift in Sources */,

BIN
PaiAi/Paiai.xcodeproj/project.xcworkspace/xcuserdata/FFIB.xcuserdatad/UserInterfaceState.xcuserstate


+ 9 - 1
PaiAi/PaiaiUIKit/Reusable/Extension/UIKit/UIImageExt.swift

@@ -22,9 +22,17 @@ public extension UIImage {
22 22
         let renderer = UIGraphicsImageRenderer(size: outputSize)
23 23
         return renderer.jpegData(withCompressionQuality: quality) { _ in
24 24
             let content = UIGraphicsGetCurrentContext()
25
-            content?.draw(cgImage!, in: CGRect.init(origin: CGPoint.zero, size: outputSize))
25
+            content?.draw(cgImage!, in: CGRect(origin: CGPoint.zero, size: outputSize))
26 26
         }
27 27
     }
28
+    
29
+    func combineTo(image: UIImage, proportion: CGFloat, size: CGSize) {
30
+        let renderer = UIGraphicsImageRenderer(size: size)
31
+        renderer.image(actions: { context in
32
+            context.currentImage.draw(in: CGRect.init(x: 0, y: 0, width: size.width * proportion, height: size.height))
33
+            image.draw(in: CGRect.init(x: size.width * proportion, y: 0, width: size.width * (1 - proportion), height: size.height))
34
+        })
35
+    }
28 36
 }
29 37
 
30 38
 public extension UIImage {

+ 54 - 183
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationController/NavigationBar.swift

@@ -9,52 +9,7 @@
9 9
 import UIKit
10 10
 
11 11
 class NavigationBar: UINavigationBar {
12
-
13
-    private var currBgImage: UIImage?
14
-    private var targetBgImage: UIImage?
15
-    private var originShadowImage: UIImage?
16
-
17
-    private var hasChangedBgImage: Bool = false
18
-    private var hasChangedShadow: Bool = false
19
-    private var titleView: UIView?
20
-
21
-    var needsInteractive: Bool {
22
-        return hasChangedBgImage || hasChangedShadow
23
-    }
24
-    var bounce: Bounce = .none
25
-    var isPush: Bool = true
26
-
27
-    override var shadowImage: UIImage? {
28
-        didSet {
29
-            originShadowImage = oldValue
30
-            hasChangedShadow = true
31
-        }
32
-    }
33
-
34
-    lazy var fakeView: UIVisualEffectView = {
35
-        let val = UIVisualEffectView(effect: UIBlurEffect(style: .light))
36
-        val.frame = getNavigationBarBounds()
37
-        val.isUserInteractionEnabled = false
38
-        val.autoresizingMask = [.flexibleWidth, .flexibleHeight]
39
-
40
-        return val
41
-    }()
42
-
43
-    lazy var backgroundImageView: UIImageView = {
44
-        let view = UIImageView()
45
-        view.isUserInteractionEnabled = false
46
-        view.frame = getNavigationBarBounds().offsetBy(dx: bounds.width, dy: 0)
47
-
48
-        return view
49
-    }()
50
-
51
-    lazy var shadowImageView: UIImageView = {
52
-        let view = UIImageView()
53
-        view.frame = CGRect(x: 0, y: bounds.height, width: bounds.width, height: 0.5)
54
-
55
-        return view
56
-    }()
57
-
12
+    
58 13
     override init(frame: CGRect) {
59 14
         super.init(frame: frame)
60 15
     }
@@ -62,170 +17,86 @@ class NavigationBar: UINavigationBar {
62 17
     required init?(coder aDecoder: NSCoder) {
63 18
         fatalError("init(coder:) has not been implemented")
64 19
     }
65
-    override func setBackgroundImage(_ backgroundImage: UIImage?, for barMetrics: UIBarMetrics) {
66
-        currBgImage = self.backgroundImage(for: .default)
67
-        targetBgImage = backgroundImage
68
-        hasChangedBgImage = true
69
-    }
70 20
 
71
-    override func setBackgroundImage(_ backgroundImage: UIImage?,
72
-                                     for barPosition: UIBarPosition,
73
-                                     barMetrics: UIBarMetrics) {
74
-        currBgImage = self.backgroundImage(for: .default)
75
-        targetBgImage = backgroundImage
76
-        hasChangedBgImage = true
21
+    func getNavigationBarBounds() -> CGRect {
22
+        let statusHeight = UIApplication.shared.statusBarFrame.height
23
+        return CGRect(x: 0, y: -statusHeight, width: bounds.width, height: bounds.height + statusHeight)
77 24
     }
78 25
 
79
-    func setBackgroundImage() {
80
-        super.setBackgroundImage(targetBgImage, for: .any, barMetrics: .default)
26
+    override func value(forUndefinedKey key: String) -> Any? {
27
+        return nil
81 28
     }
29
+}
82 30
 
31
+public extension UINavigationBar {
83 32
     func getBarBackground() -> UIView? {
84
-       return value(forKeyPath: "_backgroundView") as? UIView
33
+        return value(forKeyPath: "_backgroundView") as? UIView
85 34
     }
86
-
87
-    func getContentView() -> UIView? {
35
+    
36
+    func getBarContentView() -> UIView? {
88 37
         for val in subviews {
89
-            if let contentClass = NSClassFromString("_UINavigationBarContentView"), val.isKind(of: contentClass) {
38
+            if let contentClass = NSClassFromString("_UINavigationBarContentView"),
39
+                val.isKind(of: contentClass) {
90 40
                 return val
91 41
             }
92 42
         }
93 43
         return nil
94 44
     }
95
-
45
+    
96 46
     func getShadowView() -> UIView? {
97 47
         guard let barBackground = getBarBackground() else { return nil }
98
-        for val in barBackground.subviews where val.bounds.height == 0.5 {
99
-            return val
48
+        for view in barBackground.subviews where view.bounds.height == 0.5 {
49
+            return view
100 50
         }
101 51
         return nil
102 52
     }
103
-
104
-    func getNavigationBarBounds() -> CGRect {
105
-        let statusHeight = UIApplication.shared.statusBarFrame.height
106
-        return CGRect(x: 0, y: -statusHeight, width: bounds.width, height: bounds.height + statusHeight)
53
+    
54
+    internal func apply(for configure: NavigationBarConfiguration) {
55
+        isHidden = configure.isHidden
56
+        isTranslucent = configure.isTranslucent
57
+        
58
+        barStyle = configure.barStyle
59
+        shadowImage = configure.shadowImage
60
+        setBackgroundImage(configure.backgroundImage, for: .default)
107 61
     }
108
-
109
-    override func value(forUndefinedKey key: String) -> Any? {
110
-        return nil
62
+    
63
+    internal convenience init(configure: NavigationBarConfiguration) {
64
+        self.init()
65
+        apply(for: configure)
111 66
     }
112 67
 }
113 68
 
114
-/// NavigationBar transition
115
-extension NavigationBar {
116
-    func constructViewHierarchy() {
117
-        setupShadowView()
118
-        setupBackgroundImageView()
119
-
120
-        guard let barBackground = getBarBackground() else { return }
121
-
122
-        insertSubview(shadowImageView, aboveSubview: barBackground)
123
-        insertSubview(backgroundImageView, aboveSubview: barBackground)
124
-        insertSubview(fakeView, belowSubview: backgroundImageView)
125
-        layoutIfNeeded()
126
-    }
127
-
128
-    private func setupShadowView() {
129
-        if let image = originShadowImage, image.size == CGSize.zero {
130
-            shadowImageView.image = image
131
-        } else {
132
-            shadowImageView.backgroundColor = UIColor(red: 0, green: 0, blue: 0,
133
-                                                      alpha: 77.0 / 255)
134
-        }
135
-
136
-        shadowImageView.alpha = originShadowImage == nil ? 1 : 0
137
-        getShadowView()?.isHidden = true
138
-    }
139
-
140
-    private func setupBackgroundImageView() {
141
-        if isPush {
142
-            fakeView.alpha = 0
143
-            backgroundImageView.image = targetBgImage
144
-        } else {
145
-            setBackgroundImage()
146
-            fakeView.alpha = 1
147
-            backgroundImageView.image = currBgImage
148
-        }
149
-    }
150
-
151
-    /// interactivePopGestureRecognizer
152
-    func transitionAnimationWithPercent(_ percent: CGFloat) {
153
-        switch bounce {
154
-        case .forward, .none:
155
-            transitionShadowAnimationWithPercent(percent)
156
-            transitionBackgroundAnimationWithPercent(percent)
157
-        case .backward:
158
-            transitionShadowAnimationWithPercent(1 - percent)
159
-            transitionBackgroundAnimationWithPercent(1 - percent)
160
-        }
161
-    }
162
-
163
-    func transitionAnimation() {
164
-        transitionShadowAnimation()
165
-        transitionBackgroundAnimation()
166
-    }
167
-
168
-    private func transitionShadowAnimation() {
169
-        guard hasChangedShadow else { return }
170
-        shadowImageView.alpha = originShadowImage == nil ? 0 : 1
171
-//        if originShadowImage == nil {
172
-//            shadowImageView.alpha = isInteractive ? (1 - percent) * 1 : 0
173
-//        } else {
174
-//            shadowImageView.alpha = isInteractive ? percent * 1 : 1
175
-//        }
69
+public extension UIToolbar {
70
+    func getBarBackground() -> UIView? {
71
+        return value(forKeyPath: "_backgroundView") as? UIView
176 72
     }
177
-
178
-    private func transitionBackgroundAnimation() {
179
-        guard hasChangedBgImage else { return }
180
-        if isPush {
181
-            fakeView.alpha = 1
182
-            backgroundImageView.frame.origin.x = 0
183
-        } else {
184
-            fakeView.alpha = 0
185
-            backgroundImageView.frame.origin.x = bounds.width
73
+    
74
+    func getShadowView() -> UIView? {
75
+        guard let barBackground = getBarBackground() else { return nil }
76
+        for view in barBackground.subviews where view.bounds.height == 0.5 {
77
+            return view
186 78
         }
79
+        return nil
187 80
     }
188
-
189
-    private func transitionShadowAnimationWithPercent(_ percent: CGFloat) {
190
-        guard hasChangedShadow else { return }
191
-        shadowImageView.alpha = originShadowImage == nil ? (1 - percent) * 1 : percent * 1
192
-    }
193
-
194
-    private func transitionBackgroundAnimationWithPercent(_ percent: CGFloat) {
195
-        guard hasChangedBgImage else { return }
196
-        fakeView.alpha = (1 - percent) * 1
197
-        backgroundImageView.frame.origin.x = percent * bounds.width
198
-    }
199
-
200
-    func clear() {
201
-
202
-        if isPush && hasChangedBgImage { setBackgroundImage() }
203
-
204
-        if !isPush && bounce == .backward && hasChangedBgImage {
205
-            targetBgImage = currBgImage
206
-            setBackgroundImage()
207
-        }
208
-
209
-        getShadowView()?.isHidden = false
210
-
211
-        fakeView.removeFromSuperview()
212
-        shadowImageView.removeFromSuperview()
213
-        backgroundImageView.removeFromSuperview()
214
-
215
-        currBgImage = nil
216
-        targetBgImage = nil
217
-
218
-        hasChangedBgImage = false
219
-        hasChangedShadow = false
220
-
221
-        bounce = .none
81
+    
82
+    internal convenience init(configure: NavigationBarConfiguration) {
83
+        self.init()
84
+        isHidden = configure.isHidden
85
+        isTranslucent = configure.isTranslucent
86
+        
87
+        barStyle = configure.barStyle
88
+        setShadowImage(configure.shadowImage, forToolbarPosition: .any)
89
+        setBackgroundImage(configure.backgroundImage, forToolbarPosition: .any, barMetrics: .default)
222 90
     }
223 91
 }
224 92
 
225
-extension NavigationBar {
226
-    enum Bounce {
227
-        case none
228
-        case backward
229
-        case forward
93
+extension UIViewController {
94
+    internal func getFakeBarFrame(for navigationBar: UINavigationBar) -> CGRect? {
95
+        guard let backgroundView = navigationBar.getBarBackground(),
96
+            var frame = backgroundView.superview?.convert(backgroundView.frame, to: self.view)
97
+            else { return nil }
98
+        
99
+        frame.origin.x = self.view.bounds.origin.x
100
+        return frame
230 101
     }
231 102
 }

+ 50 - 0
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationController/NavigationBarConfiguration.swift

@@ -0,0 +1,50 @@
1
+//
2
+//  NavigationBarConfiguration.swift
3
+//  PaiaiUIKit
4
+//
5
+//  Created by ffib on 2019/5/8.
6
+//  Copyright © 2019 FFIB. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+
11
+struct NavigationBarConfiguration {
12
+    var isHidden: Bool
13
+    var isTranslucent: Bool
14
+    
15
+    var barStyle: UIBarStyle
16
+    var shadowImage: UIImage?
17
+    var backgroundImage: UIImage?
18
+    
19
+    static var `default`: NavigationBarConfiguration {
20
+        return NavigationBarConfiguration()
21
+    }
22
+    
23
+    static var transparent: NavigationBarConfiguration {
24
+        return NavigationBarConfiguration(isHidden: false, isTranslucent: true,
25
+                                          shadowImage: UIImage(), backgroundImage: UIImage())
26
+    }
27
+    
28
+    init(isHidden: Bool = false,
29
+         isTranslucent: Bool = false,
30
+         tintColor: UIColor = .black,
31
+         shadowImage: UIImage? = nil,
32
+         barTintColor: UIColor? = nil,
33
+         backgroundImage: UIImage? = nil,
34
+         barStyle: UIBarStyle = .default,
35
+         titleTextAttributes: [NSAttributedString.Key: Any] = [:]) {
36
+        self.isHidden = isHidden
37
+        self.barStyle = barStyle
38
+        self.shadowImage = shadowImage
39
+        self.isTranslucent = isTranslucent
40
+        self.backgroundImage = backgroundImage
41
+    }
42
+    
43
+    init(navigationBar: UINavigationBar) {
44
+        isHidden = navigationBar.isHidden
45
+        barStyle = navigationBar.barStyle
46
+        shadowImage = navigationBar.shadowImage
47
+        isTranslucent = navigationBar.isTranslucent
48
+        backgroundImage = navigationBar.backgroundImage(for: .default)
49
+    }
50
+}

+ 90 - 55
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationController/NavigationController.swift

@@ -9,7 +9,13 @@
9 9
 import UIKit
10 10
 
11 11
 public class NavigationController: UINavigationController {
12
-
12
+    
13
+    private var operation: Operation = .none
14
+    private var barConfigures: [UIViewController?: NavigationBarConfiguration] = [:]
15
+    
16
+    private var _fromFakeBar = UIToolbar()
17
+    private var _toFakeBar = UIToolbar()
18
+    
13 19
     override public init(rootViewController: UIViewController) {
14 20
         super.init(navigationBarClass: NavigationBar.classForCoder(), toolbarClass: nil)
15 21
         self.viewControllers = [rootViewController]
@@ -28,41 +34,67 @@ public class NavigationController: UINavigationController {
28 34
         delegate = self
29 35
         interactivePopGestureRecognizer?.delegate = self
30 36
         interactivePopGestureRecognizer?.isEnabled = true
31
-
32
-        interactivePopGestureRecognizer?.addTarget(self,
33
-                                                   action: #selector(handlePop(gestureRecognizer:)))
34 37
     }
38
+    
39
+    public override func viewDidLayoutSubviews() {
40
+        super.viewDidLayoutSubviews()
41
+        if operation == .none { return }
42
+        navigationBar.getBarBackground()?.alpha = 0
43
+    }
44
+}
35 45
 
36
-    @objc
37
-    private func handlePop(gestureRecognizer: UIPanGestureRecognizer) {
38
-        guard let navBar = navigationBar as? NavigationBar else { return }
39
-        if gestureRecognizer.state == .began { navBar.isPush = false }
40
-
41
-        guard navBar.needsInteractive else { return }
42
-
43
-        let percent = gestureRecognizer.translation(in: view).x / view.bounds.width
44
-
45
-        if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
46
-            navBar.transitionAnimationWithPercent(percent)
46
+fileprivate extension NavigationController {
47
+    
48
+    func setFakeNavigationBar() {
49
+        UIView.setAnimationsEnabled(false)
50
+        guard let to = transitionCoordinator?.viewController(forKey: .to),
51
+            let from = transitionCoordinator?.viewController(forKey: .from) else { return }
52
+        
53
+        switch self.operation {
54
+        case .push:
55
+            barConfigures[to] = NavigationBarConfiguration(navigationBar: navigationBar)
56
+        case .pop:
57
+            navigationBar.setBackgroundImage(barConfigures[to]?.backgroundImage, for: .default)
58
+        default:
59
+            break
47 60
         }
61
+        
62
+        setToFakeNavigationBar(for: to)
63
+        setFromFakeNavigationBar(for: from)
64
+        
65
+        navigationBar.apply(for: .transparent)
66
+        UIView.setAnimationsEnabled(true)
67
+        
68
+        if barConfigures[to]?.isHidden != barConfigures[from]?.isHidden {
69
+            setNavigationBarHidden(barConfigures[to]?.isHidden ?? false, animated: true)
70
+        }
71
+    }
48 72
 
49
-        guard gestureRecognizer.state == .ended
50
-            || gestureRecognizer.state == .cancelled
51
-            || gestureRecognizer.state == .failed,
52
-            let coordinator = transitionCoordinator else { return }
53
-
54
-        navBar.bounce = percent < 0.5 ? .backward : .forward
55
-        let durationPercent = Double(percent < 0.5 ? coordinator.percentComplete : (1 - coordinator.percentComplete))
56
-        UIView.animate(withDuration: coordinator.transitionDuration * durationPercent,
57
-                       delay: 0,
58
-                       usingSpringWithDamping: 1,
59
-                       initialSpringVelocity: coordinator.completionVelocity,
60
-                       options: [],
61
-                       animations: {
62
-                        navBar.transitionAnimationWithPercent(1)
63
-        }, completion: { _ in
64
-            navBar.clear()
65
-        })
73
+    func setFromFakeNavigationBar(for from: UIViewController) {
74
+        if let navBarFrame = from.getFakeBarFrame(for: navigationBar) {
75
+            _fromFakeBar = UIToolbar(configure: barConfigures[from] ?? .default)
76
+            _fromFakeBar.delegate = self
77
+            _fromFakeBar.frame = navBarFrame
78
+            from.view.addSubview(_fromFakeBar)
79
+        }
80
+    }
81
+    
82
+    func setToFakeNavigationBar(for to: UIViewController) {
83
+        if let navBarFrame = to.getFakeBarFrame(for: navigationBar) {
84
+            _toFakeBar = UIToolbar(configure: barConfigures[to] ?? .default)
85
+            _toFakeBar.delegate = self
86
+            _toFakeBar.frame = navBarFrame
87
+            to.view.addSubview(_toFakeBar)
88
+        }
89
+    }
90
+    
91
+    func clearFake() {
92
+        _fromFakeBar.removeFromSuperview()
93
+        _toFakeBar.removeFromSuperview()
94
+        
95
+        guard let from = transitionCoordinator?.viewController(forKey: .from),
96
+            operation == .pop else { return }
97
+        barConfigures.removeValue(forKey: from)
66 98
     }
67 99
 }
68 100
 
@@ -72,37 +104,34 @@ extension NavigationController: UINavigationControllerDelegate {
72 104
                                      animationControllerFor operation: UINavigationController.Operation,
73 105
                                      from fromVC: UIViewController,
74 106
                                      to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
75
-        (navigationBar as? NavigationBar)?.isPush = operation == .push
107
+        self.operation = operation
76 108
         return nil
77 109
     }
78 110
 
79 111
     public func navigationController(_ navigationController: UINavigationController,
80 112
                                      willShow viewController: UIViewController,
81 113
                                      animated: Bool) {
82
-        guard let navBar = navigationBar as? NavigationBar,
83
-            navBar.needsInteractive else { return }
84
-
85
-        guard let coordinator = transitionCoordinator,
86
-            animated else {
87
-                navBar.setBackgroundImage()
88
-                navBar.clear()
89
-                return
114
+        if operation == .none {
115
+            self.barConfigures[viewController] = NavigationBarConfiguration(navigationBar: navigationBar)
116
+            return
90 117
         }
91
-
92
-        navBar.constructViewHierarchy()
93
-
94
-        guard !coordinator.isInteractive else { return }
95
-
96
-        coordinator.animate(alongsideTransition: { (transitionContext) in
97
-            DispatchQueue.main.async {
98
-                UIView.beginAnimations(nil, context: nil)
99
-                UIView.setAnimationCurve(transitionContext.completionCurve)
100
-                UIView.setAnimationDuration(transitionContext.transitionDuration)
101
-                navBar.transitionAnimation()
102
-                UIView.commitAnimations()
118
+        
119
+        transitionCoordinator?.animate(alongsideTransition: { context in
120
+            if context.isInteractive {
121
+                self.operation = .pop
122
+            }
123
+            self.setFakeNavigationBar()
124
+        }, completion: { context in
125
+            let vc: UIViewController?
126
+            if context.isCancelled {
127
+                self.operation = .push
128
+                vc = context.viewController(forKey: .from)
129
+            } else {
130
+                vc = context.viewController(forKey: .to)
103 131
             }
104
-        }, completion: { (_) in
105
-            navBar.clear()
132
+            self.navigationBar.getBarBackground()?.alpha = 1
133
+            self.navigationBar.apply(for: self.barConfigures[vc] ?? .default)
134
+            self.clearFake()
106 135
         })
107 136
     }
108 137
 }
@@ -115,3 +144,9 @@ extension NavigationController: UIGestureRecognizerDelegate {
115 144
         return true
116 145
     }
117 146
 }
147
+
148
+extension NavigationController: UIToolbarDelegate {
149
+    public func position(for bar: UIBarPositioning) -> UIBarPosition {
150
+        return .top
151
+    }
152
+}

+ 3 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/PageViewController/PageViewController.swift

@@ -69,7 +69,9 @@ open class PageViewController: UIViewController {
69 69
         contentRect = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
70 70
 
71 71
         if #available(iOS 11, *) {
72
-            scrollView.contentInsetAdjustmentBehavior = .never
72
+            scrollView.contentInsetAdjustmentBehavior = .automatic
73
+        } else {
74
+            automaticallyAdjustsScrollViewInsets = false
73 75
         }
74 76
 
75 77
         constructViewHierarchy()

+ 5 - 4
PaiAi/PaiaiUIKit/Reusable/UIKit/QR/QRCodeScanView.swift

@@ -82,14 +82,15 @@ import CoreImage
82 82
     }
83 83
 
84 84
     @objc func start() {
85
-        let queue = DispatchQueue(label: "FFIB.startScan.com")
86
-        queue.async {
87
-            self.qrscanner?.startScan()
85
+//        let queue = DispatchQueue(label: "FFIB.startScan.com")
86
+//        queue.async {
87
+        
88 88
             DispatchQueue.main.async {
89
+                self.qrscanner?.startScan()
89 90
                 self.qrmaskView?.startAnimation()
90 91
                 self.indicatorView.stopAnimating()
91 92
             }
92
-        }
93
+//        }
93 94
     }
94 95
 
95 96
     public func openLight() {

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/QR/QRCodeScanner.swift

@@ -83,7 +83,7 @@ class QRCodeScanner: NSObject {
83 83
     }
84 84
     func startScan() {
85 85
         setScanArea()
86
-        captureSession.startRunning()
86
+//        captureSession.startRunning()
87 87
     }
88 88
 
89 89
     func stopScan() {

+ 3 - 1
PaiAi/Paiai_iOS/App/AppCoordinator.swift

@@ -70,11 +70,13 @@ fileprivate extension AppCoordinator {
70 70
 
71 71
         let homeCoordinator = HomeCoordinator(homeVC,
72 72
                                               navigationController: navigationController,
73
+                                              containerViewController: containerViewController,
73 74
                                               userInfoViewModel: shareUserInfoViewModel)
74 75
         coordinate(to: homeCoordinator).subscribe().disposed(by: disposeBag)
75 76
 
76 77
         let messageCoordinator = MessageCoordinator(messageVC,
77
-                                                    navigationController: navigationController)
78
+                                                    navigationController: navigationController,
79
+                                                    containerViewController: containerViewController)
78 80
         coordinate(to: messageCoordinator).subscribe().disposed(by: disposeBag)
79 81
 
80 82
         containerViewController.pageItems = [PageItem(title: "首页",

+ 1 - 0
PaiAi/Paiai_iOS/App/ContainerViewController.swift

@@ -61,6 +61,7 @@ public final class ContainerViewController: PageViewController {
61 61
     }
62 62
 
63 63
     func setupNavigationBar() {
64
+        navigationController?.navigationBar.isTranslucent = true
64 65
         navigationController?.navigationBar.shadowImage = UIImage()
65 66
         navigationController?.navigationBar.tintColor = UIColor.white
66 67
         navigationController?.navigationBar.barTintColor = UIColor.white

+ 2 - 2
PaiAi/Paiai_iOS/App/Group/GroupViewController.swift

@@ -52,10 +52,10 @@ final class GroupViewController: UIViewController {
52 52
     override func viewDidLoad() {
53 53
         super.viewDidLoad()
54 54
         initalize()
55
+        navigationController?.navigationBar.setBackgroundImage(UIImage.Navigation.background, for: .default)
55 56
     }
56 57
 
57 58
     override func viewWillAppear(_ animated: Bool) {
58
-        navigationController?.navigationBar.setBackgroundImage(UIImage.Navigation.background, for: .default)
59 59
         super.viewWillAppear(animated)
60 60
     }
61 61
 
@@ -82,7 +82,7 @@ final class GroupViewController: UIViewController {
82 82
     }
83 83
 
84 84
     deinit {
85
-        collectionView.endAllRefreshing()
85
+        collectionView.removeAllPullToRefresh()
86 86
     }
87 87
 }
88 88
 

+ 3 - 1
PaiAi/Paiai_iOS/App/Home/HomeCoordinator.swift

@@ -13,14 +13,16 @@ import PaiaiDataKit
13 13
 class HomeCoordinator: BaseCoordinator<Void> {
14 14
 
15 15
     var homeViewController: HomeViewController
16
+    var containerViewController: ContainerViewController
16 17
     var shareUserInfoViewModel: UserInfoViewModel
17 18
 
18 19
     init(_ viewController: HomeViewController,
19 20
          navigationController: UINavigationController,
21
+         containerViewController: ContainerViewController,
20 22
          userInfoViewModel: UserInfoViewModel) {
21 23
         self.homeViewController = viewController
22 24
         self.shareUserInfoViewModel = userInfoViewModel
23
-
25
+        self.containerViewController = containerViewController
24 26
         super.init(navigationController: navigationController, viewController: viewController)
25 27
     }
26 28
 

+ 2 - 2
PaiAi/Paiai_iOS/App/Home/HomeViewController.swift

@@ -36,7 +36,7 @@ final class HomeViewController: UIViewController {
36 36
         collectionView.register(UINib(nibName: "PhotoCell",
37 37
                                       bundle: Bundle(identifier: "com.Paiai-iOS")),
38 38
                                 forCellWithReuseIdentifier: "photoCell")
39
-
39
+        
40 40
         setup()
41 41
         binding()
42 42
     }
@@ -62,7 +62,7 @@ final class HomeViewController: UIViewController {
62 62
     }
63 63
 
64 64
     deinit {
65
-        collectionView.endAllRefreshing()
65
+        collectionView.removeAllPullToRefresh()
66 66
     }
67 67
 }
68 68
 

+ 2 - 1
PaiAi/Paiai_iOS/App/Home/ScanQRViewController.swift

@@ -23,6 +23,7 @@ final class ScanQRViewController: UIViewController {
23 23
     override func viewDidLoad() {
24 24
         super.viewDidLoad()
25 25
         scanView.delegate = self
26
+        setNavigationBar()
26 27
         viewModel.join(code: "http://pai.ai/g/SpA5be3")
27 28
     }
28 29
 
@@ -32,8 +33,8 @@ final class ScanQRViewController: UIViewController {
32 33
     }
33 34
 
34 35
     override func viewWillAppear(_ animated: Bool) {
35
-        setNavigationBar()
36 36
         super.viewWillAppear(animated)
37
+        
37 38
     }
38 39
 
39 40
     override func viewWillDisappear(_ animated: Bool) {

+ 2 - 1
PaiAi/Paiai_iOS/App/Message/MessageCoordinator.swift

@@ -14,7 +14,8 @@ class MessageCoordinator: BaseCoordinator<Void> {
14 14
     fileprivate let messageViewController: MessageViewController
15 15
 
16 16
     init(_ viewController: MessageViewController,
17
-         navigationController: UINavigationController) {
17
+         navigationController: UINavigationController,
18
+         containerViewController: ContainerViewController) {
18 19
         messageViewController = viewController
19 20
         super.init(navigationController: navigationController, viewController: viewController)
20 21
     }

+ 1 - 1
PaiAi/Paiai_iOS/App/Message/MessageListViewController.swift

@@ -91,7 +91,7 @@ final class MessageListViewController: UIViewController {
91 91
     }
92 92
 
93 93
     deinit {
94
-        tableView.endAllRefreshing()
94
+        tableView.removeAllPullToRefresh()
95 95
     }
96 96
 }
97 97
 

+ 1 - 1
PaiAi/Paiai_iOS/App/Mine/MineGroupViewController.swift

@@ -58,7 +58,7 @@ final class MineGroupViewController: UIViewController {
58 58
     }
59 59
 
60 60
     deinit {
61
-        tableView.endAllRefreshing()
61
+        tableView.removeAllPullToRefresh()
62 62
     }
63 63
 }
64 64
 

+ 1 - 1
PaiAi/Paiai_iOS/App/Mine/MineOrderViewController.swift

@@ -55,7 +55,7 @@ final class MineOrderViewController: UIViewController {
55 55
     }
56 56
 
57 57
     deinit {
58
-        tableView.endAllRefreshing()
58
+        tableView.removeAllPullToRefresh()
59 59
     }
60 60
 }
61 61