Pārlūkot izejas kodu

feat: 调整自定义导航栏实现逻辑

陈文艺 2 mēneši atpakaļ
vecāks
revīzija
a11f306d0b
24 mainītis faili ar 379 papildinājumiem un 412 dzēšanām
  1. 1 1
      Lanu.xcodeproj/project.pbxproj
  2. 2 2
      Lanu/Common/Extension/UIScrollView+Extension.swift
  3. 18 18
      Lanu/Common/Keyboard/LNKeyboardManager.swift
  4. 2 6
      Lanu/Common/Views/Base/LNViewController.swift
  5. 4 4
      Lanu/Common/Views/LNPopupView.swift
  6. 1 1
      Lanu/Common/Views/Selection/LNHourRangePickerPanel.swift
  7. 70 1
      Lanu/Localizable.xcstrings
  8. 56 5
      Lanu/Manager/Account/LNAccountManager.swift
  9. 9 2
      Lanu/Manager/GameMate/LNGameMateManager.swift
  10. 5 66
      Lanu/Manager/Profile/LNProfileManager.swift
  11. 1 0
      Lanu/Views/Game/Join/Input/SkillInfo/LNJoinUsSkillFieldsEditView.swift
  12. 31 57
      Lanu/Views/Game/OrderCenter/LNOrderAcceptSettingsViewController.swift
  13. 2 1
      Lanu/Views/Game/OrderCenter/Skill/LNSkillCreateViewController.swift
  14. 6 6
      Lanu/Views/Game/OrderCenter/Skill/LNSkillReviewViewController.swift
  15. 2 2
      Lanu/Views/IM/Chat/InputMenu/LNIMChatTextInputView.swift
  16. 2 2
      Lanu/Views/IM/Chat/LNIMChatViewController.swift
  17. 1 1
      Lanu/Views/IM/ConversationList/LNIMConversationCell.swift
  18. 25 115
      Lanu/Views/Login/LNLoginPanel.swift
  19. 4 10
      Lanu/Views/Login/Phone/LNLoginCaptchaInputViewController.swift
  20. 75 10
      Lanu/Views/Login/Phone/LNLoginPhoneInputViewController.swift
  21. 42 35
      Lanu/Views/Login/Setup/LNBaseInfoSetupViewController.swift
  22. 9 21
      Lanu/Views/Login/Setup/LNGenderSetupViewController.swift
  23. 3 19
      Lanu/Views/Login/Setup/LNInterestSetupViewController.swift
  24. 8 27
      Lanu/Views/Wallet/LNWalletViewController.swift

+ 1 - 1
Lanu.xcodeproj/project.pbxproj

@@ -183,11 +183,11 @@
 				Views/Game/MateList/LNGameMateListViewController.swift,
 				Views/Game/OrderCenter/LNGameMateCenterViewController.swift,
 				Views/Game/OrderCenter/LNOrderAcceptSettingsViewController.swift,
-				Views/Game/OrderCenter/Skill/LNSkillCreatedReviewViewController.swift,
 				Views/Game/OrderCenter/Skill/LNSkillCreateViewController.swift,
 				Views/Game/OrderCenter/Skill/LNSkillEditViewController.swift,
 				Views/Game/OrderCenter/Skill/LNSkillFieldsEditView.swift,
 				Views/Game/OrderCenter/Skill/LNSkillManagerViewController.swift,
+				Views/Game/OrderCenter/Skill/LNSkillReviewViewController.swift,
 				Views/Game/OrderCenter/Visitors/LNVisitorItemCell.swift,
 				Views/Game/OrderCenter/Visitors/LNVisitorsViewController.swift,
 				Views/Game/Skill/Edit/LNSkillFieldBaseEditView.swift,

+ 2 - 2
Lanu/Common/Extension/UIScrollView+Extension.swift

@@ -24,7 +24,7 @@ extension UIScrollView: LNKeyboardNotify {
         LNEventDeliver.addObserver(self)
     }
     
-    func onKeybaordWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard let curInput, curInput.isDescendant(of: self) else { return }
         
         originContentInset = contentInset
@@ -54,7 +54,7 @@ extension UIScrollView: LNKeyboardNotify {
         setContentOffset(.init(x: curOffset.x, y: curOffset.y + availableOffset + remain), animated: true)
     }
     
-    func onKeybaordWillHide(curInput: UIView?) {
+    func onKeyboardWillHide(curInput: UIView?) {
         guard let curInput, curInput.isDescendant(of: self) else { return }
         
         contentInset = originContentInset

+ 18 - 18
Lanu/Common/Keyboard/LNKeyboardManager.swift

@@ -8,22 +8,22 @@
 import Foundation
 
 protocol LNKeyboardNotify {
-    func onKeybaordWillShow(curInput: UIView?, keyboardHeight: CGFloat)
-    func onKeybaordShow(curInput: UIView?, keyboardHeight: CGFloat)
-    func onKeybaordDidShow(curInput: UIView?, keyboardHeight: CGFloat)
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat)
+    func onKeyboardShow(curInput: UIView?, keyboardHeight: CGFloat)
+    func onKeyboardDidShow(curInput: UIView?, keyboardHeight: CGFloat)
     
-    func onKeybaordWillHide(curInput: UIView?)
-    func onKeybaordHide(curInput: UIView?)
-    func onKeybaordDidHide(curInput: UIView?)
+    func onKeyboardWillHide(curInput: UIView?)
+    func onKeyboardHide(curInput: UIView?)
+    func onKeyboardDidHide(curInput: UIView?)
 }
 extension LNKeyboardNotify {
-    func onKeybaordWillShow(curInput: UIView?, keyboardHeight: CGFloat) {}
-    func onKeybaordShow(curInput: UIView?, keyboardHeight: CGFloat) {}
-    func onKeybaordDidShow(curInput: UIView?, keyboardHeight: CGFloat) {}
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat) {}
+    func onKeyboardShow(curInput: UIView?, keyboardHeight: CGFloat) {}
+    func onKeyboardDidShow(curInput: UIView?, keyboardHeight: CGFloat) {}
     
-    func onKeybaordWillHide(curInput: UIView?) {}
-    func onKeybaordHide(curInput: UIView?) {}
-    func onKeybaordDidHide(curInput: UIView?) {}
+    func onKeyboardWillHide(curInput: UIView?) {}
+    func onKeyboardHide(curInput: UIView?) {}
+    func onKeyboardDidHide(curInput: UIView?) {}
 }
 
 class LNKeyboardManager {
@@ -60,7 +60,7 @@ class LNKeyboardManager {
             let visibleView = (curInput as? UITextInput)?.visibleView ?? curInput
             
             LNEventDeliver.notifyEvent {
-                ($0 as? LNKeyboardNotify)?.onKeybaordWillShow(curInput: visibleView, keyboardHeight: keyboardHeight)
+                ($0 as? LNKeyboardNotify)?.onKeyboardWillShow(curInput: visibleView, keyboardHeight: keyboardHeight)
             }
             
             // 应用动画参数调整UI(使视图动画与键盘动画同步)
@@ -70,11 +70,11 @@ class LNKeyboardManager {
                 .AnimationOptions(rawValue: UInt(animationCurveRawValue)),
                            animations: {
                 LNEventDeliver.notifyEvent {
-                    ($0 as? LNKeyboardNotify)?.onKeybaordShow(curInput: visibleView, keyboardHeight: keyboardHeight)
+                    ($0 as? LNKeyboardNotify)?.onKeyboardShow(curInput: visibleView, keyboardHeight: keyboardHeight)
                 }
             }) { _ in
                 LNEventDeliver.notifyEvent {
-                    ($0 as? LNKeyboardNotify)?.onKeybaordDidShow(curInput: visibleView, keyboardHeight: keyboardHeight)
+                    ($0 as? LNKeyboardNotify)?.onKeyboardDidShow(curInput: visibleView, keyboardHeight: keyboardHeight)
                 }
             }
         }
@@ -95,7 +95,7 @@ class LNKeyboardManager {
             let visibleView = (curInput as? UITextInput)?.visibleView ?? curInput
             
             LNEventDeliver.notifyEvent {
-                ($0 as? LNKeyboardNotify)?.onKeybaordWillHide(curInput: visibleView)
+                ($0 as? LNKeyboardNotify)?.onKeyboardWillHide(curInput: visibleView)
             }
             // 应用动画参数调整UI(使视图动画与键盘动画同步)
             UIView.animate(withDuration: animationDuration,
@@ -104,11 +104,11 @@ class LNKeyboardManager {
                 .AnimationOptions(rawValue: UInt(animationCurveRawValue)),
                            animations: {
                 LNEventDeliver.notifyEvent {
-                    ($0 as? LNKeyboardNotify)?.onKeybaordHide(curInput: visibleView)
+                    ($0 as? LNKeyboardNotify)?.onKeyboardHide(curInput: visibleView)
                 }
             }) { _ in
                 LNEventDeliver.notifyEvent {
-                    ($0 as? LNKeyboardNotify)?.onKeybaordDidHide(curInput: visibleView)
+                    ($0 as? LNKeyboardNotify)?.onKeyboardDidHide(curInput: visibleView)
                 }
             }
         }

+ 2 - 6
Lanu/Common/Views/Base/LNViewController.swift

@@ -56,12 +56,6 @@ class LNViewController: UIViewController {
         }
     }
     
-    override func viewDidAppear(_ animated: Bool) {
-        super.viewDidAppear(animated)
-        
-        fakeView.backgroundColor = view.backgroundColor
-    }
-    
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         
@@ -83,5 +77,7 @@ class LNViewController: UIViewController {
             navBar.standardAppearance = appearance   // 常规状态的外观
             navBar.compactAppearance = appearance
         }
+        
+        fakeView.backgroundColor = view.backgroundColor
     }
 }

+ 4 - 4
Lanu/Common/Views/LNPopupView.swift

@@ -153,7 +153,7 @@ extension LNPopupView {
 }
 
 extension LNPopupView: LNKeyboardNotify {
-    func onKeybaordWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard let curInput, curInput.isDescendant(of: self) == true else { return }
         let containerY = bounds.height - container.bounds.height
         let editViewY = curInput.convert(curInput.bounds, to: container).maxY
@@ -165,17 +165,17 @@ extension LNPopupView: LNKeyboardNotify {
         }
     }
     
-    func onKeybaordShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard curInput?.isDescendant(of: self) == true else { return }
         layoutIfNeeded()
     }
     
-    func onKeybaordWillHide(curInput: UIView?) {
+    func onKeyboardWillHide(curInput: UIView?) {
         guard curInput?.isDescendant(of: self) == true else { return }
         moveToShowupPosition()
     }
     
-    func onKeybaordHide(curInput: UIView?) {
+    func onKeyboardHide(curInput: UIView?) {
         guard curInput?.isDescendant(of: self) == true else { return }
         layoutIfNeeded()
     }

+ 1 - 1
Lanu/Common/Views/Selection/LNHourRangePickerPanel.swift

@@ -50,7 +50,7 @@ class LNHourRangePickerPanel: LNPopupView {
 extension LNHourRangePickerPanel: UIPickerViewDataSource, UIPickerViewDelegate {
     func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
         if pickerView == toPicker, isRelative {
-            23
+            24
         } else {
             24
         }

+ 70 - 1
Lanu/Localizable.xcstrings

@@ -8609,7 +8609,7 @@
         "en" : {
           "stringUnit" : {
             "state" : "translated",
-            "value" : "Opennig..."
+            "value" : "Opening..."
           }
         },
         "id" : {
@@ -8878,6 +8878,75 @@
           }
         }
       }
+    },
+    "B00099" : {
+      "extractionState" : "manual",
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Other Login Methods"
+          }
+        },
+        "id" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Metode login lainnya"
+          }
+        },
+        "zh-Hans" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "其他登录方式"
+          }
+        }
+      }
+    },
+    "B00100" : {
+      "extractionState" : "manual",
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "All Day"
+          }
+        },
+        "id" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Sepanjang Hari"
+          }
+        },
+        "zh-Hans" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "全天"
+          }
+        }
+      }
+    },
+    "B00101" : {
+      "extractionState" : "manual",
+      "localizations" : {
+        "en" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Review"
+          }
+        },
+        "id" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "Verifikasi"
+          }
+        },
+        "zh-Hans" : {
+          "stringUnit" : {
+            "state" : "translated",
+            "value" : "审核"
+          }
+        }
+      }
     }
   },
   "version" : "1.1"

+ 56 - 5
Lanu/Manager/Account/LNAccountManager.swift

@@ -7,6 +7,7 @@
 
 import Foundation
 import GoogleSignIn
+import AuthenticationServices
 
 
 protocol LNAccountManagerNotify {
@@ -36,7 +37,7 @@ var hasLogin: Bool {
     !myUid.isEmpty
 }
 
-class LNAccountManager {
+class LNAccountManager: NSObject {
     static let shared = LNAccountManager()
     
     private(set) var token = LNUserDefaults[.token, ""] {
@@ -57,7 +58,36 @@ class LNAccountManager {
         captchaRemain == 0
     }
     
-    private init() {
+    func doGoogleLogin(_ vc: UIViewController) {
+        showLoading()
+        GIDSignIn.sharedInstance.signIn(withPresenting: vc) { [weak self] result, err in
+            guard let self else { return }
+            guard err == nil,
+                  let result,
+                  let token = result.user.idToken?.tokenString else {
+                dismissLoading()
+                return
+            }
+            self.loginByGoogle(data: token) { _ in
+                dismissLoading()
+            }
+        }
+    }
+    
+    func doAppleLogin() {
+        let provider = ASAuthorizationAppleIDProvider()
+        let request = provider.createRequest()
+        request.requestedScopes = [.fullName, .email]
+        let controller = ASAuthorizationController(authorizationRequests: [request])
+        controller.delegate = self
+//            controller.presentationContextProvider = self
+        showLoading()
+        controller.performRequests()
+    }
+    
+    private override init() {
+        super.init()
+        
         let clientID = if LNAppConfig.shared.curEnv == .test {
             "981655295954-noc65ii1gfgpq3mrc0r75t7gq66v57bj.apps.googleusercontent.com"
         } else {
@@ -67,7 +97,28 @@ class LNAccountManager {
         GIDSignIn.sharedInstance.configuration = GIDConfiguration(clientID: clientID)
     }
 }
- 
+
+extension LNAccountManager: ASAuthorizationControllerDelegate {
+    func authorizationController(controller: ASAuthorizationController,
+                                 didCompleteWithAuthorization authorization: ASAuthorization) {
+        guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
+              let token = credential.identityToken,
+              let tokenStr = String(data: token, encoding: .utf8)
+        else {
+            dismissLoading()
+            return
+        }
+        
+        loginByApple(data: tokenStr) { _ in
+            dismissLoading()
+        }
+    }
+    
+    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: any Error) {
+        dismissLoading()
+    }
+}
+
 extension LNAccountManager {
     func loginByToken(handler: ((Bool) -> Void)? = nil) {
         LNHttpManager.shared.refreshToken { [weak self] res, err in
@@ -87,7 +138,7 @@ extension LNAccountManager {
         }
     }
     
-    func loginByGoogle(data: String, handler: ((Bool) -> Void)? = nil) {
+    private func loginByGoogle(data: String, handler: ((Bool) -> Void)? = nil) {
         LNHttpManager.shared.loginByGoogle(token: data) { [weak self] response, err in
             guard let self else { return }
             guard err == nil, let response else {
@@ -104,7 +155,7 @@ extension LNAccountManager {
         }
     }
     
-    func loginByApple(data: String, handler: ((Bool) -> Void)? = nil) {
+    private func loginByApple(data: String, handler: ((Bool) -> Void)? = nil) {
         LNHttpManager.shared.loginByApple(token: data) { [weak self] response, err in
             guard let self else { return }
             guard err == nil, let response else {

+ 9 - 2
Lanu/Manager/GameMate/LNGameMateManager.swift

@@ -378,12 +378,19 @@ extension LNGameMateManager {
     }
 }
 
-extension LNGameMateManager: LNAccountManagerNotify {
+extension LNGameMateManager: LNAccountManagerNotify, LNProfileManagerNotify {
     func onUserLogout() {
     }
     
     func onUserLogin() {
-        getGameMateManagerInfo()
+    }
+    
+    func onUserInfoChanged(userInfo: LNUserProfileVO) {
+        guard userInfo.userNo.isMyUid else { return }
+        
+        if userInfo.playmate {
+            getGameMateManagerInfo()
+        }
     }
 }
 

+ 5 - 66
Lanu/Manager/Profile/LNProfileManager.swift

@@ -28,12 +28,6 @@ class LNProfileManager {
     
     fileprivate var myUserInfo: LNUserProfileVO = LNUserProfileVO()
     
-    private let lock = NSLock()
-    private var profileCached: [String: LNUserProfileVO] = [:]
-    
-    typealias fetchProfileBlock = (LNUserProfileVO?) -> Void
-    private var requests: [String: [fetchProfileBlock]] = [:]
-    
     private var randomProfile: LNRandomProfileResponse?
     
     private let captchaCoolDown = 60
@@ -46,50 +40,6 @@ class LNProfileManager {
     private init() {
         LNEventDeliver.addObserver(self)
     }
-    
-    func userInfo(for uid: String, forceNet: Bool = false,
-                  queue: DispatchQueue = .main,
-                  completion: @escaping (LNUserProfileVO?) -> Void) {
-        lock.lock()
-        if let cached = profileCached[uid] {
-            lock.unlock()
-            completion(cached)
-            return
-        }
-        var array = requests[uid] ?? []
-        array.append(completion)
-        requests[uid] = array
-        
-        if array.count > 1 {
-            lock.unlock()
-            return
-        }
-        lock.unlock()
-        
-        getUserProfile(uid: uid, queue: .global()) { [weak self] info in
-            guard let self else { return }
-            guard let info else {
-                lock.lock()
-                let handlers = requests.removeValue(forKey: uid)
-                lock.unlock()
-                queue.asyncIfNotGlobal {
-                    handlers?.forEach {
-                        $0(nil)
-                    }
-                }
-                return
-            }
-            lock.lock()
-            let handlers = requests.removeValue(forKey: uid)
-            lock.unlock()
-            
-            queue.asyncIfNotGlobal {
-                handlers?.forEach {
-                    $0(info)
-                }
-            }
-        }
-    }
 }
 
 extension LNProfileManager {
@@ -126,7 +76,10 @@ extension LNProfileManager {
             guard let self else { return }
             if let res, err == nil {
                 res.list.forEach {
-                    self.updateUserInfo(info: $0)
+                    if $0.userNo.isMyUid {
+                        self.myUserInfo = $0
+                    }
+                    self.notifyUserInfoChanged(newInfo: $0)
                 }
             } else {
                 showToast(err?.errorDesc)
@@ -186,11 +139,10 @@ extension LNProfileManager {
     func bindPhone(code: String, phone: String,
                    queue: DispatchQueue = .main,
                    captcha: String, handler: @escaping (Bool) -> Void) {
-        LNHttpManager.shared.bindPhone(code: code, phone: phone, captcha: captcha) { [weak self] err in
+        LNHttpManager.shared.bindPhone(code: code, phone: phone, captcha: captcha) { err in
             queue.asyncIfNotGlobal {
                 handler(err == nil)
             }
-            guard let self else { return }
             if let err {
                 showToast(err.errorDesc)
             }
@@ -221,19 +173,6 @@ extension LNProfileManager {
     }
 }
 
-extension LNProfileManager {
-    private func updateUserInfo(info: LNUserProfileVO) {
-        if info.userNo.isMyUid {
-            myUserInfo = info
-        }
-        lock.lock()
-        profileCached[info.userNo] = info
-        lock.unlock()
-        
-        notifyUserInfoChanged(newInfo: info)
-    }
-}
-
 extension LNProfileManager: LNAccountManagerNotify {
     func onUserLogin() {
         reloadMyProfile()

+ 1 - 0
Lanu/Views/Game/Join/Input/SkillInfo/LNJoinUsSkillFieldsEditView.swift

@@ -120,6 +120,7 @@ extension LNJoinUsSkillFieldsEditView {
             LNGameMateManager.shared.createSkill(info: info) { [weak self] success in
                 dismissLoading()
                 guard let self else { return }
+                guard success else { return }
                 pushToJoinUsReview()
             }
         }

+ 31 - 57
Lanu/Views/Game/OrderCenter/LNOrderAcceptSettingsViewController.swift

@@ -22,6 +22,10 @@ class LNOrderAcceptSettingsViewController: LNViewController {
     private let timeLabel = UILabel()
     private var selectTime: (from: Int, to: Int) = (0, 1) {
         didSet {
+            if selectTime.from + 24 == selectTime.to || selectTime.from == selectTime.to {
+                timeLabel.text = .init(key: "B00100")
+                return
+            }
             let fromTime = String(format: "%02d:00", selectTime.from)
             let toTime: String = if selectTime.to > 23 {
                 .init(key: "B00084") + String(format: "%02d:00", selectTime.to - 24)
@@ -64,7 +68,10 @@ extension LNOrderAcceptSettingsViewController {
             let components = config.timeRange.components(separatedBy: "-")
             if components.count == 2 {
                 let from = extractHourFromTimeString(components[0])
-                let to = extractHourFromTimeString(components[1])
+                var to = extractHourFromTimeString(components[1])
+                if to <= from {
+                    to += 24
+                }
                 selectTime = (from, to)
             } else {
                 selectTime = (0, 1)
@@ -76,7 +83,7 @@ extension LNOrderAcceptSettingsViewController {
     }
     
     private func saveConfig() {
-        let timeRange = String(format: "%02d:00", selectTime.from) + "-" + String(format: "%02d:00", selectTime.to)
+        let timeRange = String(format: "%02d:00", selectTime.from) + "-" + String(format: "%02d:00", selectTime.to > 24 ? selectTime.to - 24 : selectTime.to)
         if let config,
             config.weekNums == selectDate,
             config.timeRange == timeRange {
@@ -176,15 +183,10 @@ extension LNOrderAcceptSettingsViewController {
             make.top.equalToSuperview().offset(12)
         }
         
-        stackView.addArrangedSubview(buildTime())
-        stackView.addArrangedSubview(buildDate())
-    }
-    
-    private func buildTime() -> UIView {
-        let container = UIView()
-        container.layer.cornerRadius = 12
-        container.backgroundColor = .fill
-        container.onTap { [weak self] in
+        timeLabel.font = .body_s
+        timeLabel.textColor = .text_4
+        let timeRangeView = buildItemView(title: .init(key: "B00079"), contentView: timeLabel)
+        timeRangeView.onTap { [weak self] in
             guard let self else { return }
             let panel = LNHourRangePickerPanel()
             panel.setTitles(.init(key: "B00082"), desc: .init(key: "B00083"))
@@ -195,47 +197,12 @@ extension LNOrderAcceptSettingsViewController {
             }
             panel.popup()
         }
-        container.snp.makeConstraints { make in
-            make.height.equalTo(60)
-        }
-        
-        let arrow = UIImageView.arrowImageView(size: 14)
-        arrow.tintColor = .text_4
-        container.addSubview(arrow)
-        arrow.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.trailing.equalToSuperview().offset(-12)
-        }
-        
-        timeLabel.font = .body_s
-        timeLabel.textColor = .text_4
-        container.addSubview(timeLabel)
-        timeLabel.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.trailing.equalTo(arrow.snp.leading).offset(-2)
-        }
+        stackView.addArrangedSubview(timeRangeView)
         
-        let titleLabel = UILabel()
-        titleLabel.font = .heading_h4
-        titleLabel.textColor = .text_5
-        titleLabel.text = .init(key: "B00079")
-        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
-        titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
-        container.addSubview(titleLabel)
-        titleLabel.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.leading.equalToSuperview().offset(12)
-            make.trailing.lessThanOrEqualTo(timeLabel.snp.leading).offset(-12)
-        }
-        
-        return container
-    }
-    
-    private func buildDate() -> UIView {
-        let container = UIView()
-        container.layer.cornerRadius = 12
-        container.backgroundColor = .fill
-        container.onTap { [weak self] in
+        dateLabel.font = .body_s
+        dateLabel.textColor = .text_4
+        let weekdayView = buildItemView(title: .init(key: "B00080"), contentView: dateLabel)
+        weekdayView.onTap { [weak self] in
             guard let self else { return }
             let formatter = DateFormatter()
             formatter.locale = curLocal
@@ -253,6 +220,13 @@ extension LNOrderAcceptSettingsViewController {
             }
             panel.popup()
         }
+        stackView.addArrangedSubview(weekdayView)
+    }
+    
+    private func buildItemView(title: String, contentView: UIView) -> UIView {
+        let container = UIView()
+        container.layer.cornerRadius = 12
+        container.backgroundColor = .fill
         container.snp.makeConstraints { make in
             make.height.equalTo(60)
         }
@@ -265,10 +239,10 @@ extension LNOrderAcceptSettingsViewController {
             make.trailing.equalToSuperview().offset(-12)
         }
         
-        dateLabel.font = .body_s
-        dateLabel.textColor = .text_4
-        container.addSubview(dateLabel)
-        dateLabel.snp.makeConstraints { make in
+        contentView.setContentHuggingPriority(.defaultLow, for: .horizontal)
+        contentView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
+        container.addSubview(contentView)
+        contentView.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
             make.trailing.equalTo(arrow.snp.leading).offset(-2)
         }
@@ -276,14 +250,14 @@ extension LNOrderAcceptSettingsViewController {
         let titleLabel = UILabel()
         titleLabel.font = .heading_h4
         titleLabel.textColor = .text_5
-        titleLabel.text = .init(key: "B00080")
+        titleLabel.text = title
         titleLabel.setContentHuggingPriority(.required, for: .horizontal)
         titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
         container.addSubview(titleLabel)
         titleLabel.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
             make.leading.equalToSuperview().offset(12)
-            make.trailing.lessThanOrEqualTo(dateLabel.snp.leading).offset(-12)
+            make.trailing.lessThanOrEqualTo(contentView.snp.leading).offset(-12)
         }
         
         return container

+ 2 - 1
Lanu/Views/Game/OrderCenter/Skill/LNSkillCreateViewController.swift

@@ -97,7 +97,8 @@ extension LNSkillCreateViewController {
             LNGameMateManager.shared.createSkill(info: input) { [weak self] success in
                 dismissLoading()
                 guard let self else { return }
-                view.pushToSkillCreatedReview()
+                guard success else { return }
+                view.pushToSkillReview()
             }
         }
     }

+ 6 - 6
Lanu/Views/Game/OrderCenter/Skill/LNSkillCreatedReviewViewController.swift → Lanu/Views/Game/OrderCenter/Skill/LNSkillReviewViewController.swift

@@ -1,5 +1,5 @@
 //
-//  LNSkillCreatedReviewViewController.swift
+//  LNSkillReviewViewController.swift
 //  Gami
 //
 //  Created by OneeChan on 2026/1/26.
@@ -11,7 +11,7 @@ import SnapKit
 
 
 extension UIView {
-    func pushToSkillCreatedReview(_ animated: Bool = true) {
+    func pushToSkillReview() {
         let vc = LNJoinUsReviewViewController()
         
         let index = navigationController?.viewControllers.lastIndex (where: { $0 is LNSkillManagerViewController })
@@ -20,13 +20,13 @@ extension UIView {
             viewControllers.append(vc)
             navigationController?.setViewControllers(viewControllers, animated: true)
         } else {
-            navigationController?.pushViewController(vc, animated: animated)
+            navigationController?.pushViewController(vc, animated: true)
         }
     }
 }
 
 
-class LNSkillCreatedReviewViewController: LNViewController {
+class LNSkillReviewViewController: LNViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
@@ -34,11 +34,11 @@ class LNSkillCreatedReviewViewController: LNViewController {
     }
 }
 
-extension LNSkillCreatedReviewViewController {
+extension LNSkillReviewViewController {
     private func setupViews() {
         navigationBarColor = .clear
         
-        title = .init(key: "B00031")
+        title = .init(key: "B00101")
         
         let bg = UIImageView()
         bg.image = .icJoinUsReviewBg

+ 2 - 2
Lanu/Views/IM/Chat/InputMenu/LNIMChatTextInputView.swift

@@ -109,13 +109,13 @@ extension LNIMChatTextInputView: UITextViewDelegate {
 }
 
 extension LNIMChatTextInputView: LNKeyboardNotify {
-    func onKeybaordWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard curInput == inputField else { return }
         
         emojiHeight?.update(offset: keyboardHeight)
     }
     
-    func onKeybaordShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard curInput == inputField else { return }
         layoutIfNeeded()
     }

+ 2 - 2
Lanu/Views/IM/Chat/LNIMChatViewController.swift

@@ -194,12 +194,12 @@ extension LNIMChatViewController: UITableViewDataSource, UITableViewDelegate {
 }
 
 extension LNIMChatViewController: LNKeyboardNotify {
-    func onKeybaordWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard curInput?.isDescendant(of: view) == true else { return }
         tableView.scrollToBottom(animated: false)
     }
     
-    func onKeybaordShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard curInput?.isDescendant(of: view) == true else { return }
         tableView.scrollToBottom(animated: true)
     }

+ 1 - 1
Lanu/Views/IM/ConversationList/LNIMConversationCell.swift

@@ -62,7 +62,7 @@ class LNIMConversationCell: UITableViewCell {
         curItem = item
         
         if let userId = item.userID, !userId.isImOfficialId {
-            LNProfileManager.shared.userInfo(for: userId) { [weak self] info in
+            LNProfileManager.shared.getUserProfile(uid: userId) { [weak self] info in
                 guard let self else { return }
                 guard let info, info.userNo == curItem?.userID else { return }
                 

+ 25 - 115
Lanu/Views/Login/LNLoginPanel.swift

@@ -8,8 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import GoogleSignIn
-import AuthenticationServices
 
 
 private weak var curLoginPanel: LNLoginPanel? = nil
@@ -45,22 +43,6 @@ extension LNLoginPanel: LNAccountManagerNotify {
     }
 }
 
-extension LNLoginPanel: ASAuthorizationControllerDelegate {
-    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
-        guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
-              let token = credential.identityToken,
-              let tokenStr = String(data: token, encoding: .utf8)
-        else {
-            return
-        }
-        
-        LNAccountManager.shared.loginByApple(data: tokenStr)
-    }
-    
-    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: any Error) {
-    }
-}
-
 extension LNLoginPanel {
     private func setupViews() {
         container.backgroundColor = .text_5.withAlphaComponent(0.7)
@@ -94,13 +76,26 @@ extension LNLoginPanel {
         let email = buildEmail()
         stackView.addArrangedSubview(email)
 #endif
-        let phone = buildPhoneLogin()
+        let phone = buildLoginItem(icon: .icLoginPhone, title: .init(key: "B00019"), textColor: .text_1, color: .primary_3)
+        phone.addAction(UIAction(handler: { [weak self] _ in
+            guard let self else { return }
+            pushToLoginPhone()
+        }), for: .touchUpInside)
         stackView.addArrangedSubview(phone)
         
-        let apple = buildAppleLogin()
+        let apple = buildLoginItem(icon: .icApple, title: .init(key: "A00285"), textColor: .text_1, color: .init(hex: "#0B0B0A"))
+        apple.addAction(UIAction(handler: { [weak self] _ in
+            guard self != nil else { return }
+            LNAccountManager.shared.doAppleLogin()
+        }), for: .touchUpInside)
         stackView.addArrangedSubview(apple)
         
-        let google = buildGoogleLogin()
+        let google = buildLoginItem(icon: .icGoogle, title: .init(key: "A00115"), textColor: .text_5, color: .fill)
+        google.addAction(UIAction(handler: { [weak self] _ in
+            guard let self else { return }
+            guard let topVC = navigationController?.topViewController else { return }
+            LNAccountManager.shared.doGoogleLogin(topVC)
+        }), for: .touchUpInside)
         stackView.addArrangedSubview(google)
         
         let tipsLabel = UILabel()
@@ -123,9 +118,9 @@ extension LNLoginPanel {
         }
     }
     
-    private func buildPhoneLogin() -> UIView {
+    private func buildLoginItem(icon: UIImage, title: String, textColor: UIColor, color: UIColor) -> UIButton {
         let button = UIButton()
-        button.setBackgroundImage(.primary_3, for: .normal)
+        button.setBackgroundImage(UIImage.image(for: color), for: .normal)
         button.layer.cornerRadius = 24
         button.clipsToBounds = true
         button.snp.makeConstraints { make in
@@ -133,107 +128,22 @@ extension LNLoginPanel {
         }
         
         let ic = UIImageView()
-        ic.image = .icLoginPhone
+        ic.image = icon
         button.addSubview(ic)
         ic.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
             make.leading.equalToSuperview().offset(12)
         }
         
-        let title = UILabel()
-        title.font = .heading_h3
-        title.textColor = .text_1
-        title.text = .init(key: "B00019")
-        button.addSubview(title)
-        title.snp.makeConstraints { make in
+        let titleLabel = UILabel()
+        titleLabel.font = .heading_h3
+        titleLabel.textColor = textColor
+        titleLabel.text = title
+        button.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
             make.center.equalToSuperview()
         }
         
-        button.addAction(UIAction(handler: { [weak self] _ in
-            guard let self else { return }
-            pushToLoginPhone()
-        }), for: .touchUpInside)
-        
-        return button
-    }
-    
-    private func buildAppleLogin() -> UIView {
-        let button = UIButton()
-        button.setBackgroundImage(UIImage.image(for: .init(hex: "#0B0B0A")), for: .normal)
-        button.layer.cornerRadius = 24
-        button.clipsToBounds = true
-        button.snp.makeConstraints { make in
-            make.height.equalTo(48)
-        }
-        
-        let ic = UIImageView()
-        ic.image = .icApple
-        button.addSubview(ic)
-        ic.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.leading.equalToSuperview().offset(12)
-        }
-        
-        let title = UILabel()
-        title.font = .heading_h3
-        title.textColor = .text_1
-        title.text = .init(key: "A00285")
-        button.addSubview(title)
-        title.snp.makeConstraints { make in
-            make.center.equalToSuperview()
-        }
-        
-        button.addAction(UIAction(handler: { [weak self] _ in
-            guard let self else { return }
-            let provider = ASAuthorizationAppleIDProvider()
-            let request = provider.createRequest()
-            request.requestedScopes = [.fullName, .email]
-            let controller = ASAuthorizationController(authorizationRequests: [request])
-            controller.delegate = self
-//            controller.presentationContextProvider = self
-            controller.performRequests()
-        }), for: .touchUpInside)
-        
-        return button
-    }
-    
-    private func buildGoogleLogin() -> UIView {
-        let button = UIButton()
-        button.setBackgroundImage(.fill, for: .normal)
-        button.layer.cornerRadius = 24
-        button.clipsToBounds = true
-        button.snp.makeConstraints { make in
-            make.height.equalTo(48)
-        }
-        
-        let ic = UIImageView()
-        ic.image = .icGoogle
-        button.addSubview(ic)
-        ic.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.leading.equalToSuperview().offset(22)
-        }
-        
-        let title = UILabel()
-        title.font = .heading_h3
-        title.textColor = .text_5
-        title.text = .init(key: "A00115")
-        button.addSubview(title)
-        title.snp.makeConstraints { make in
-            make.center.equalToSuperview()
-        }
-        
-        button.addAction(UIAction(handler: { [weak self] _ in
-            guard let self else { return }
-            guard let topVC = navigationController?.topViewController else { return }
-            GIDSignIn.sharedInstance.signIn(withPresenting: topVC) { [weak self] result, err in
-                guard self != nil else { return }
-                guard err == nil, let result else { return }
-                guard let token = result.user.idToken?.tokenString else { return }
-                LNAccountManager.shared.loginByGoogle(data: token)
-            }
-        }), for: .touchUpInside)
-        
         return button
     }
     

+ 4 - 10
Lanu/Views/Login/Phone/LNLoginCaptchaInputViewController.swift

@@ -100,30 +100,24 @@ extension LNLoginCaptchaInputViewController: LNCaptchaInputViewDelegate {
 
 extension LNLoginCaptchaInputViewController {
     private func setupViews() {
-        showNavigationBar = false
+        navigationBarColor = .clear
         
         let cover = UIImageView(image: .icLoginProfileBg)
         view.addSubview(cover)
         cover.snp.makeConstraints { make in
-            make.top.horizontalEdges.equalToSuperview()
-        }
-        
-        let fakeNav = LNFakeNaviBar()
-        fakeNav.showBackButton()
-        view.addSubview(fakeNav)
-        fakeNav.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
+            make.top.equalToSuperview().offset(-UIView.navigationBarHeight - UIView.statusBarHeight)
         }
         
         let textView = buildTextView()
         view.addSubview(textView)
         textView.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(22)
-            make.top.equalTo(fakeNav.snp.bottom).offset(20)
+            make.top.equalToSuperview().offset(20)
         }
         
         captchaInput.delegate = self
+        captchaInput.startInput()
         view.addSubview(captchaInput)
         captchaInput.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(22)

+ 75 - 10
Lanu/Views/Login/Phone/LNLoginPhoneInputViewController.swift

@@ -65,9 +65,14 @@ extension LNLoginPhoneInputViewController {
             sections.append((key, map[key]) as! (code: String, list: [LNCountryCodeVO]))
         }
         
-        let item: LNCountryCodeVO? = list.first {
+        var item: LNCountryCodeVO? = list.first {
             $0.code == LNAppConfig.shared.curLang.countryCode
         }
+        if item == nil {
+            item = list.first {
+                $0.code == LNAppLanguage.indonesian.countryCode
+            }
+        }
         if let item {
             countryIcon.sd_setImage(with: URL(string: item.icon))
             countryCodeLabel.text = item.num
@@ -94,20 +99,13 @@ extension LNLoginPhoneInputViewController {
     }
     
     private func setupViews() {
-        showNavigationBar = false
+        navigationBarColor = .clear
         
         let cover = UIImageView(image: .icLoginPhoneBg)
         view.addSubview(cover)
         cover.snp.makeConstraints { make in
-            make.top.horizontalEdges.equalToSuperview()
-        }
-        
-        let fakeNav = LNFakeNaviBar()
-        fakeNav.showBackButton()
-        view.addSubview(fakeNav)
-        fakeNav.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
+            make.top.equalToSuperview().offset(-UIView.navigationBarHeight - UIView.statusBarHeight)
         }
         
         let paragraphStyle = NSMutableParagraphStyle()
@@ -152,6 +150,13 @@ extension LNLoginPhoneInputViewController {
             make.top.equalTo(phoneInput.snp.bottom).offset(24)
         }
         
+        let loginMethods = buildOtherLoginMethod()
+        container.addSubview(loginMethods)
+        loginMethods.snp.makeConstraints { make in
+            make.horizontalEdges.equalToSuperview()
+            make.bottom.equalToSuperview().offset(view.commonBottomInset)
+        }
+        
         view.onTap { [weak self] in
             guard let self else { return }
             view.endEditing(true)
@@ -269,6 +274,66 @@ extension LNLoginPhoneInputViewController {
         
         return confirmButton
     }
+    
+    private func buildOtherLoginMethod() -> UIView {
+        let container = UIView()
+        
+        let titleLabel = UILabel()
+        titleLabel.text = .init(key: "B00099")
+        titleLabel.font = .body_m
+        titleLabel.textColor = .text_3
+        titleLabel.textAlignment = .center
+        container.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.horizontalEdges.equalToSuperview().inset(24)
+            make.top.equalToSuperview()
+        }
+        
+        let stackView = UIStackView()
+        stackView.axis = .horizontal
+        stackView.spacing = 62
+        container.addSubview(stackView)
+        stackView.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.leading.greaterThanOrEqualToSuperview()
+            make.top.equalTo(titleLabel.snp.bottom).offset(20)
+            make.bottom.equalToSuperview()
+        }
+        
+        let google = buildLoginMethod(icon: .icGoogle)
+        google.onTap { [weak self] in
+            guard let self else { return }
+            LNAccountManager.shared.doGoogleLogin(self)
+        }
+        stackView.addArrangedSubview(google)
+        
+        let apple = buildLoginMethod(icon: .icApple.withTintColor(.init(hex: "#0B0B0A"), renderingMode: .alwaysOriginal))
+        apple.onTap { [weak self] in
+            guard self != nil else { return }
+            LNAccountManager.shared.doAppleLogin()
+        }
+        stackView.addArrangedSubview(apple)
+        
+        return container
+    }
+    
+    private func buildLoginMethod(icon: UIImage) -> UIView {
+        let container = UIView()
+        container.backgroundColor = .fill_2
+        container.layer.cornerRadius = 20
+        container.snp.makeConstraints { make in
+            make.width.height.equalTo(40)
+        }
+        
+        let imageView = UIImageView()
+        imageView.image = icon
+        container.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+        }
+        
+        return container
+    }
 }
 
 #if DEBUG

+ 42 - 35
Lanu/Views/Login/Setup/LNBaseInfoSetupViewController.swift

@@ -8,6 +8,7 @@
 import Foundation
 import UIKit
 import SnapKit
+import Combine
 
 
 extension UIView {
@@ -34,8 +35,7 @@ enum LNAvatarModifyType: CaseIterable {
 class LNBaseInfoSetupViewController: LNViewController {
     private let updateConfig: LNProfileUpdateConfig
     
-    private let fakeNavBar = LNFakeNaviBar()
-    
+    private let container = UIView()
     private let avatar = LNUploadImageView()
     private let nameInputField = UITextField()
     private let randomView = UIView()
@@ -63,8 +63,6 @@ class LNBaseInfoSetupViewController: LNViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
-        showNavigationBar = false
-        
         setupViews()
         loadRandomProfile()
         LNEventDeliver.addObserver(self)
@@ -98,7 +96,7 @@ extension LNBaseInfoSetupViewController {
                 checkNextButtonEnable()
             }
         }
-        panel.popup(view)
+        panel.popup()
     }
     
     private func loadRandomProfile() {
@@ -134,22 +132,36 @@ extension LNBaseInfoSetupViewController: LNUploadImageViewDelegate {
 }
 
 extension LNBaseInfoSetupViewController: LNKeyboardNotify {
-    func onKeybaordShow(curInput: UIView?, keyboardHeight: CGFloat) {
+    func onKeyboardWillShow(curInput: UIView?, keyboardHeight: CGFloat) {
         guard let curInput, curInput.isDescendant(of: view) else { return }
-        let frame = curInput.superview!.convert(curInput.frame, to: view)
+        
+        let frame = curInput.convert(curInput.frame, to: view)
         let offset = keyboardHeight - (view.bounds.height - CGRectGetMaxY(frame) - 20)
         if offset > 0 {
-            var frame = view.frame
-            frame.origin.y -= offset
-            view.frame = frame
+            container.snp.updateConstraints { make in
+                make.top.equalToSuperview().offset(-offset)
+            }
+        }
+    }
+    
+    func onKeyboardShow(curInput: UIView?, keyboardHeight: CGFloat) {
+        guard curInput == nameInputField else { return }
+        
+        view.layoutIfNeeded()
+    }
+    
+    func onKeyboardWillHide(curInput: UIView?) {
+        guard curInput == nameInputField else { return }
+        
+        container.snp.updateConstraints { make in
+            make.top.equalToSuperview().offset(0)
         }
     }
     
-    func onKeybaordHide(curInput: UIView?) {
+    func onKeyboardHide(curInput: UIView?) {
         guard curInput == nameInputField else { return }
-        var frame = view.frame
-        frame.origin.y = 0
-        view.frame = frame
+        
+        view.layoutIfNeeded()
     }
 }
 
@@ -160,38 +172,39 @@ extension LNBaseInfoSetupViewController {
     }
     
     private func setupViews() {
+        navigationBarColor = .clear
         view.backgroundColor = .primary_1
-        view.onTap { [weak self] in
+        
+        view.addSubview(container)
+        container.onTap { [weak self] in
             guard let self else { return }
             self.view.endEditing(true)
         }
+        container.snp.makeConstraints { make in
+            make.top.equalToSuperview().offset(0)
+            make.horizontalEdges.equalToSuperview()
+            make.height.equalToSuperview()
+        }
         
         let bg = UIImageView()
         bg.image = .icLoginProfileBg
-        view.addSubview(bg)
+        container.addSubview(bg)
         bg.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
-        }
-        
-        let navBar = buildFakeNavBar()
-        view.addSubview(navBar)
-        navBar.snp.makeConstraints { make in
-            make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
+            make.top.equalToSuperview().offset(-UIView.navigationBarHeight - UIView.statusBarHeight)
         }
         
         let titleView = buildTitles()
-        view.addSubview(titleView)
+        container.addSubview(titleView)
         titleView.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(22)
-            make.top.equalTo(fakeNavBar.snp.bottom).offset(22)
+            make.top.equalToSuperview().offset(22)
         }
         
         let baseInfo = buildBaseInfoView()
-        view.addSubview(baseInfo)
+        container.addSubview(baseInfo)
         baseInfo.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
+            make.centerY.equalToSuperview().multipliedBy(0.8)
             make.horizontalEdges.equalToSuperview().inset(22)
         }
         
@@ -209,7 +222,7 @@ extension LNBaseInfoSetupViewController {
             updateConfig.avatar = avatar.imageUrl ?? ""
             view.pushToInterestSetup(updateConfig)
         }), for: .touchUpInside)
-        view.addSubview(nextButton)
+        container.addSubview(nextButton)
         nextButton.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(16)
             make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-4)
@@ -408,12 +421,6 @@ extension LNBaseInfoSetupViewController {
 //        
 //        return container
 //    }
-    
-    private func buildFakeNavBar() -> UIView {
-        fakeNavBar.showBackButton()
-        
-        return fakeNavBar
-    }
 }
 
 #if DEBUG

+ 9 - 21
Lanu/Views/Login/Setup/LNGenderSetupViewController.swift

@@ -19,8 +19,6 @@ extension UIView {
 
 
 class LNGenderSetupViewController: LNViewController {
-    private let fakeNavBar = LNFakeNaviBar()
-    
     private let maleIc = UIImageView()
     private let maleBg = UIImageView()
     private let maleLabel = UILabel()
@@ -60,7 +58,6 @@ class LNGenderSetupViewController: LNViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
-        showNavigationBar = false
         enableDragBack = false
         
         setupViews()
@@ -69,32 +66,29 @@ class LNGenderSetupViewController: LNViewController {
 
 extension LNGenderSetupViewController {
     private func setupViews() {
+        navigationBarColor = .clear
+        
         let bg = UIImageView()
         bg.image = .icLoginProfileBg
         view.addSubview(bg)
         bg.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
+            make.top.equalToSuperview().offset(-UIView.navigationBarHeight - UIView.statusBarHeight)
         }
         
-        let navBar = buildFakeNavBar()
-        view.addSubview(navBar)
-        navBar.snp.makeConstraints { make in
-            make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
-        }
+        setupNavigationBar()
         
         let titles = buildTitles()
         view.addSubview(titles)
         titles.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(22)
-            make.top.equalTo(fakeNavBar.snp.bottom).offset(22)
+            make.top.equalToSuperview().offset(22)
         }
         
         let gender = buildGenderView()
         view.addSubview(gender)
         gender.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
+            make.centerY.equalToSuperview().multipliedBy(0.8)
             make.horizontalEdges.equalToSuperview().inset(16)
         }
         
@@ -234,8 +228,8 @@ extension LNGenderSetupViewController {
         return container
     }
     
-    private func buildFakeNavBar() -> UIView {
-        fakeNavBar.showBackButton { [weak self] in
+    private func setupNavigationBar() {
+        customBack = { [weak self] in
             guard let self else { return }
             navigationController?.popViewController(animated: true)
             LNAccountManager.shared.logout()
@@ -251,13 +245,7 @@ extension LNGenderSetupViewController {
             let config = LNProfileUpdateConfig()
             view.pushToBaseInfoSetup(config)
         }), for: .touchUpInside)
-        fakeNavBar.actionView.addSubview(skipButton)
-        skipButton.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.trailing.equalToSuperview().offset(-16)
-        }
-        
-        return fakeNavBar
+        setRightButton(skipButton)
     }
 }
 

+ 3 - 19
Lanu/Views/Login/Setup/LNInterestSetupViewController.swift

@@ -21,8 +21,6 @@ extension UIView {
 class LNInterestSetupViewController: LNViewController {
     private let updateConfig: LNProfileUpdateConfig
     
-    private let fakeNavBar = LNFakeNaviBar()
-    
     private let horizentalSpace = 22.0
     private let lineSpace = 8.0
     private let itemSpacing = 13.0
@@ -55,8 +53,6 @@ class LNInterestSetupViewController: LNViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
-        showNavigationBar = false
-        
         setupViews()
     }
     
@@ -130,27 +126,21 @@ extension LNInterestSetupViewController {
     
     private func setupViews() {
         view.backgroundColor = .primary_1
+        navigationBarColor = .clear
         
         let bg = UIImageView()
         bg.image = .icLoginInterestBg
         view.addSubview(bg)
         bg.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
-        }
-        
-        let navBar = buildFakeNavBar()
-        view.addSubview(navBar)
-        navBar.snp.makeConstraints { make in
-            make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
+            make.top.equalToSuperview().offset(-UIView.navigationBarHeight - UIView.statusBarHeight)
         }
         
         let titleView = buildTitles()
         view.addSubview(titleView)
         titleView.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(22)
-            make.top.equalTo(fakeNavBar.snp.bottom).offset(22)
+            make.top.equalToSuperview().offset(22)
         }
         
         let listView = buildListView()
@@ -169,12 +159,6 @@ extension LNInterestSetupViewController {
         }
     }
     
-    private func buildFakeNavBar() -> UIView {
-        fakeNavBar.showBackButton()
-        
-        return fakeNavBar
-    }
-    
     private func buildTitles() -> UIView {
         let stackView = UIStackView()
         stackView.axis = .vertical

+ 8 - 27
Lanu/Views/Wallet/LNWalletViewController.swift

@@ -48,22 +48,17 @@ extension LNWalletViewController {
     }
     
     private func setupViews() {
-        showNavigationBar = false
         view.backgroundColor = .primary_1
         
         let topCover = UIImageView()
         topCover.image = .icHomeTopBg
         view.addSubview(topCover)
         topCover.snp.makeConstraints { make in
-            make.top.leading.trailing.equalToSuperview()
+            make.leading.trailing.equalToSuperview()
+            make.top.equalToSuperview().offset(-UIView.navigationBarHeight - UIView.statusBarHeight)
         }
         
-        let naviBar = buildFakeNavBar()
-        view.addSubview(naviBar)
-        naviBar.snp.makeConstraints { make in
-            make.horizontalEdges.equalToSuperview()
-            make.top.equalToSuperview()
-        }
+        setupNavBar()
         
         let stackView = UIStackView()
         stackView.axis = .vertical
@@ -71,7 +66,7 @@ extension LNWalletViewController {
         view.addSubview(stackView)
         stackView.snp.makeConstraints { make in
             make.horizontalEdges.equalToSuperview().inset(16)
-            make.top.equalTo(naviBar.snp.bottom).offset(16)
+            make.top.equalToSuperview().offset(16)
         }
         
         stackView.addArrangedSubview(buildWallet())
@@ -81,21 +76,9 @@ extension LNWalletViewController {
         }
     }
     
-    private func buildFakeNavBar() -> UIView {
-        let fakeBar = LNFakeNaviBar()
-        
-        fakeBar.showBackButton()
-        fakeBar.backButton?.setImage(.init(systemName: "chevron.backward"), for: .normal)
-        fakeBar.backButton?.tintColor = .text_5
-        
-        let titleLabel = UILabel()
-        titleLabel.text = .init(key: "A00215")
-        titleLabel.font = .heading_h2
-        titleLabel.textColor = .text_5
-        fakeBar.actionView.addSubview(titleLabel)
-        titleLabel.snp.makeConstraints { make in
-            make.center.equalToSuperview()
-        }
+    private func setupNavBar() {
+        navigationBarColor = .clear
+        title = .init(key: "A00215")
         
         let history = UIButton()
         history.setImage(.icWalletHistory, for: .normal)
@@ -103,9 +86,7 @@ extension LNWalletViewController {
             guard let self else { return }
             view.pushToWebView(.init(url: .walletHistoryUrl, showNavigationBar: false))
         }), for: .touchUpInside)
-        fakeBar.setRightMenu(history)
-        
-        return fakeBar
+        setRightButton(history)
     }
     
     private func buildWallet() -> UIView {