Advance UIKit rewrite with AMap integration and core UI modules.
Integrate高德 SDK with simulator-safe build flags, add map views for operating area and punch points, refactor main tabs and key feature screens to UIKit with Diffable lists, and document Swift concurrency defaults in AGENTS.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -26,6 +26,7 @@ final class LoginViewController: UIViewController {
|
||||
private let privacyPolicyButton = UIButton(type: .system)
|
||||
private let loginButton = UIButton(type: .system)
|
||||
|
||||
/// 初始化实例。
|
||||
init(services: AppServices) {
|
||||
self.services = services
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
@ -36,6 +37,7 @@ final class LoginViewController: UIViewController {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
/// 视图加载完成后的 UI 初始化与数据绑定。
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = UIColor(hex: 0x0B1220)
|
||||
@ -44,6 +46,7 @@ final class LoginViewController: UIViewController {
|
||||
viewModel.applyPreferences(services.authSessionCoordinator.loginPreferences())
|
||||
}
|
||||
|
||||
/// 配置Views展示内容。
|
||||
private func configureViews() {
|
||||
backgroundImageView.contentMode = .scaleAspectFill
|
||||
backgroundImageView.clipsToBounds = true
|
||||
@ -161,6 +164,7 @@ final class LoginViewController: UIViewController {
|
||||
view.addGestureRecognizer(tap)
|
||||
}
|
||||
|
||||
/// 配置AgreementText展示内容。
|
||||
private func configureAgreementText() {
|
||||
privacyLabel.numberOfLines = 0
|
||||
privacyLabel.font = .systemFont(ofSize: AppMetrics.FontSize.subheadline)
|
||||
@ -197,6 +201,7 @@ final class LoginViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
/// 绑定ViewModel回调或数据。
|
||||
private func bindViewModel() {
|
||||
viewModel.onChange = { [weak self] in
|
||||
self?.renderViewModel()
|
||||
@ -204,6 +209,7 @@ final class LoginViewController: UIViewController {
|
||||
renderViewModel()
|
||||
}
|
||||
|
||||
/// render视图模型相关逻辑。
|
||||
private func renderViewModel() {
|
||||
if usernameField.textField.text != viewModel.username {
|
||||
usernameField.textField.text = viewModel.username
|
||||
@ -241,38 +247,46 @@ final class LoginViewController: UIViewController {
|
||||
|
||||
private weak var accountSelectionController: AccountSelectionViewController?
|
||||
|
||||
/// username变更相关逻辑。
|
||||
@objc private func usernameChanged() {
|
||||
viewModel.username = usernameField.textField.text ?? ""
|
||||
viewModel.normalizeUsernameCountryCodeIfNeeded()
|
||||
services.toastCenter.dismiss()
|
||||
}
|
||||
|
||||
/// password变更相关逻辑。
|
||||
@objc private func passwordChanged() {
|
||||
viewModel.password = passwordField.textField.text ?? ""
|
||||
services.toastCenter.dismiss()
|
||||
}
|
||||
|
||||
/// togglePrivacy相关逻辑。
|
||||
@objc private func togglePrivacy() {
|
||||
viewModel.privacyChecked.toggle()
|
||||
}
|
||||
|
||||
/// openUserAgreement相关逻辑。
|
||||
@objc private func openUserAgreement() {
|
||||
showToast("用户协议页面待接入")
|
||||
}
|
||||
|
||||
/// openPrivacyPolicy相关逻辑。
|
||||
@objc private func openPrivacyPolicy() {
|
||||
showToast("隐私政策页面待接入")
|
||||
}
|
||||
|
||||
/// 点击login的处理逻辑。
|
||||
@objc private func loginTapped() {
|
||||
view.endEditing(true)
|
||||
performLogin()
|
||||
}
|
||||
|
||||
/// dismiss键盘相关逻辑。
|
||||
@objc private func dismissKeyboard() {
|
||||
view.endEditing(true)
|
||||
}
|
||||
|
||||
/// perform登录相关逻辑。
|
||||
private func performLogin() {
|
||||
if let validationError = viewModel.validateForLogin() {
|
||||
if validationError == .privacyUnchecked {
|
||||
@ -307,6 +321,7 @@ final class LoginViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
/// 弹出AgreementSheet页面。
|
||||
private func presentAgreementSheet() {
|
||||
let controller = LoginAgreementConsentViewController(
|
||||
onOpenAgreement: { [weak self] title in
|
||||
@ -324,6 +339,7 @@ final class LoginViewController: UIViewController {
|
||||
present(controller, animated: true)
|
||||
}
|
||||
|
||||
/// 弹出AccountSelection页面。
|
||||
private func presentAccountSelection(_ payload: AccountSelectionPayload) {
|
||||
let controller = AccountSelectionViewController(
|
||||
payload: payload,
|
||||
@ -342,6 +358,7 @@ final class LoginViewController: UIViewController {
|
||||
present(navigation, animated: true)
|
||||
}
|
||||
|
||||
/// select账号相关逻辑。
|
||||
private func selectAccount(_ account: AccountSwitchAccount) {
|
||||
Task {
|
||||
do {
|
||||
@ -359,6 +376,7 @@ final class LoginViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
/// complete登录相关逻辑。
|
||||
private func completeLogin(with response: V9AuthResponse) async {
|
||||
do {
|
||||
try await services.authSessionCoordinator.completeLogin(
|
||||
@ -378,6 +396,7 @@ final class LoginViewController: UIViewController {
|
||||
}
|
||||
|
||||
extension LoginViewController: UITextFieldDelegate {
|
||||
/// text字段ShouldReturn相关逻辑。
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
if textField === usernameField.textField {
|
||||
passwordField.textField.becomeFirstResponder()
|
||||
@ -396,6 +415,7 @@ private final class LoginInputField: UIView {
|
||||
private let toggleButton = UIButton(type: .custom)
|
||||
private var isSecure = false
|
||||
|
||||
/// 初始化实例。
|
||||
init(iconName: String, placeholder: String, isSecure: Bool) {
|
||||
self.isSecure = isSecure
|
||||
super.init(frame: .zero)
|
||||
@ -450,12 +470,14 @@ private final class LoginInputField: UIView {
|
||||
nil
|
||||
}
|
||||
|
||||
/// setSecureEntry相关逻辑。
|
||||
func setSecureEntry(_ secure: Bool) {
|
||||
textField.isSecureTextEntry = secure
|
||||
let imageName = secure ? "LoginPwdInvisible" : "LoginPwdVisible"
|
||||
toggleButton.setImage(UIImage(named: imageName), for: .normal)
|
||||
}
|
||||
|
||||
/// toggleVisibility相关逻辑。
|
||||
@objc private func toggleVisibility() {
|
||||
onToggleVisibility?()
|
||||
}
|
||||
@ -467,6 +489,7 @@ private final class LoginAgreementConsentViewController: UIViewController {
|
||||
private let onOpenAgreement: (String) -> Void
|
||||
private let onAgreeAndContinue: () -> Void
|
||||
|
||||
/// 初始化实例。
|
||||
init(onOpenAgreement: @escaping (String) -> Void, onAgreeAndContinue: @escaping () -> Void) {
|
||||
self.onOpenAgreement = onOpenAgreement
|
||||
self.onAgreeAndContinue = onAgreeAndContinue
|
||||
@ -477,6 +500,7 @@ private final class LoginAgreementConsentViewController: UIViewController {
|
||||
nil
|
||||
}
|
||||
|
||||
/// 视图加载完成后的 UI 初始化与数据绑定。
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = .systemBackground
|
||||
@ -524,6 +548,7 @@ private final class LoginAgreementConsentViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
/// 点击continue的处理逻辑。
|
||||
@objc private func continueTapped() {
|
||||
dismiss(animated: true) { [onAgreeAndContinue] in
|
||||
onAgreeAndContinue()
|
||||
|
||||
Reference in New Issue
Block a user