From de8627a2302d7b4bbc20bd1425197d45890f7d6e Mon Sep 17 00:00:00 2001 From: edwinQQQ Date: Tue, 14 Oct 2025 17:46:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=20EPLoginTypesViewCo?= =?UTF-8?q?ntroller=20=E5=92=8C=20EPLoginInputView=20=E4=BB=A5=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E5=B8=83=E5=B1=80=E5=92=8C=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要变更: 1. 在 EPLoginTypesViewController 中添加了对多个 UI 组件的约束设置,确保布局更加灵活。 2. 更新了标题标签的文本内容,使用本地化字符串替代硬编码文本,提升国际化支持。 3. 在 EPLoginInputView 中为多个组件添加了自动布局支持,确保在不同屏幕尺寸下的适配性。 此更新旨在提升用户界面的可用性和美观性,确保更好的用户体验。 --- .../EPLoginTypesViewController.swift | 15 +++++-- .../E-P/NewLogin/Views/EPLoginInputView.swift | 14 ++++--- .../EPEditSettingViewController.swift | 40 +++++++++++++------ .../Controllers/EPMineViewController.m | 9 ++--- YuMi/E-P/NewMine/Services/EPMineAPIHelper.h | 5 +++ YuMi/E-P/NewMine/Services/EPMineAPIHelper.m | 23 +++++++++++ .../EPMomentPublishViewController.m | 8 +++- YuMi/E-P/NewMoments/Views/EPMomentCell.m | 3 +- 8 files changed, 89 insertions(+), 28 deletions(-) diff --git a/YuMi/E-P/NewLogin/Controllers/EPLoginTypesViewController.swift b/YuMi/E-P/NewLogin/Controllers/EPLoginTypesViewController.swift index c58d996..cb1c922 100644 --- a/YuMi/E-P/NewLogin/Controllers/EPLoginTypesViewController.swift +++ b/YuMi/E-P/NewLogin/Controllers/EPLoginTypesViewController.swift @@ -71,6 +71,7 @@ class EPLoginTypesViewController: BaseViewController { private func setupBackground() { view.addSubview(backgroundImageView) + backgroundImageView.translatesAutoresizingMaskIntoConstraints = false backgroundImageView.image = kImage(EPLoginConfig.Images.background) backgroundImageView.contentMode = .scaleAspectFill @@ -81,6 +82,7 @@ class EPLoginTypesViewController: BaseViewController { private func setupNavigationBar() { view.addSubview(backButton) + backButton.translatesAutoresizingMaskIntoConstraints = false backButton.setImage(UIImage(systemName: EPLoginConfig.Images.iconBack), for: .normal) backButton.tintColor = EPLoginConfig.Colors.textLight backButton.addTarget(self, action: #selector(handleBack), for: .touchUpInside) @@ -94,16 +96,20 @@ class EPLoginTypesViewController: BaseViewController { private func setupTitle() { view.addSubview(titleLabel) + titleLabel.translatesAutoresizingMaskIntoConstraints = false titleLabel.font = .systemFont(ofSize: EPLoginConfig.Layout.titleFontSize, weight: .bold) titleLabel.textColor = EPLoginConfig.Colors.textLight titleLabel.snp.makeConstraints { make in make.centerX.equalToSuperview() - make.top.equalTo(view.safeAreaLayoutGuide).offset(100) + make.centerY.equalTo(backButton) // 与返回按钮垂直居中对齐 } } private func setupInputViews() { + firstInputView.translatesAutoresizingMaskIntoConstraints = false + secondInputView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(firstInputView) view.addSubview(secondInputView) @@ -123,6 +129,7 @@ class EPLoginTypesViewController: BaseViewController { private func setupActionButton() { view.addSubview(actionButton) + actionButton.translatesAutoresizingMaskIntoConstraints = false actionButton.setTitle("Login", for: .normal) actionButton.setTitleColor(EPLoginConfig.Colors.textLight, for: .normal) actionButton.layer.cornerRadius = EPLoginConfig.Layout.uniformCornerRadius @@ -232,7 +239,7 @@ class EPLoginTypesViewController: BaseViewController { actionButton.setTitle("Login", for: .normal) case .emailReset: - titleLabel.text = "Recover Password" + titleLabel.text = YMLocalizedString("20.20.51_text_20") firstInputView.configure(with: EPLoginInputConfig( showAreaCode: false, showCodeButton: false, @@ -263,7 +270,7 @@ class EPLoginTypesViewController: BaseViewController { actionButton.setTitle("Confirm", for: .normal) case .phoneReset: - titleLabel.text = "Recover Password" + titleLabel.text = YMLocalizedString("20.20.51_text_20") firstInputView.configure(with: EPLoginInputConfig( showAreaCode: false, showCodeButton: false, @@ -297,6 +304,7 @@ class EPLoginTypesViewController: BaseViewController { private func setupForgotPasswordButton() { let button = UIButton(type: .system) + button.translatesAutoresizingMaskIntoConstraints = false button.setTitle("Forgot Password?", for: .normal) button.setTitleColor(EPLoginConfig.Colors.textLight, for: .normal) button.titleLabel?.font = .systemFont(ofSize: EPLoginConfig.Layout.smallFontSize) @@ -314,6 +322,7 @@ class EPLoginTypesViewController: BaseViewController { private func setupThirdInputView() { let inputView = EPLoginInputView() + inputView.translatesAutoresizingMaskIntoConstraints = false inputView.configure(with: EPLoginInputConfig( showAreaCode: false, showCodeButton: false, diff --git a/YuMi/E-P/NewLogin/Views/EPLoginInputView.swift b/YuMi/E-P/NewLogin/Views/EPLoginInputView.swift index aae19d0..6854ff5 100644 --- a/YuMi/E-P/NewLogin/Views/EPLoginInputView.swift +++ b/YuMi/E-P/NewLogin/Views/EPLoginInputView.swift @@ -94,6 +94,7 @@ class EPLoginInputView: UIView { stackView.alignment = .center stackView.distribution = .fill stackView.spacing = 8 + stackView.translatesAutoresizingMaskIntoConstraints = false addSubview(stackView) setupAreaCodeView() @@ -120,19 +121,23 @@ class EPLoginInputView: UIView { areaStackView.alignment = .center areaStackView.distribution = .fill areaStackView.spacing = 8 + areaStackView.translatesAutoresizingMaskIntoConstraints = false // 区号按钮 areaCodeButton.setTitle("+86", for: .normal) areaCodeButton.setTitleColor(EPLoginConfig.Colors.inputText, for: .normal) areaCodeButton.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) areaCodeButton.isUserInteractionEnabled = false + areaCodeButton.translatesAutoresizingMaskIntoConstraints = false // 箭头图标 areaArrowImageView.image = kImage("login_area_arrow") areaArrowImageView.contentMode = .scaleAspectFit areaArrowImageView.isUserInteractionEnabled = false + areaArrowImageView.translatesAutoresizingMaskIntoConstraints = false // 点击区域按钮 + areaTapButton.translatesAutoresizingMaskIntoConstraints = false areaTapButton.addTarget(self, action: #selector(handleAreaTap), for: .touchUpInside) areaStackView.addSubview(areaTapButton) @@ -147,7 +152,6 @@ class EPLoginInputView: UIView { areaCodeButton.snp.makeConstraints { make in make.width.lessThanOrEqualTo(60) - make.height.equalTo(stackView) } areaArrowImageView.snp.makeConstraints { make in @@ -160,6 +164,7 @@ class EPLoginInputView: UIView { // Icon (可选) iconImageView.contentMode = .scaleAspectFit iconImageView.tintColor = EPLoginConfig.Colors.icon + iconImageView.translatesAutoresizingMaskIntoConstraints = false stackView.addArrangedSubview(iconImageView) iconImageView.snp.makeConstraints { make in @@ -170,12 +175,9 @@ class EPLoginInputView: UIView { inputTextField.textColor = EPLoginConfig.Colors.textLight inputTextField.font = .systemFont(ofSize: 14) inputTextField.tintColor = EPLoginConfig.Colors.textLight + inputTextField.translatesAutoresizingMaskIntoConstraints = false inputTextField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged) stackView.addArrangedSubview(inputTextField) - - inputTextField.snp.makeConstraints { make in - make.height.equalTo(stackView) - } } @objc private func textFieldDidChange() { @@ -183,6 +185,7 @@ class EPLoginInputView: UIView { } private func setupEyeButton() { + eyeButton.translatesAutoresizingMaskIntoConstraints = false eyeButton.setImage(kImage(EPLoginConfig.Images.iconPasswordUnsee), for: .normal) eyeButton.setImage(kImage(EPLoginConfig.Images.iconPasswordSee), for: .selected) eyeButton.addTarget(self, action: #selector(handleEyeTap), for: .touchUpInside) @@ -194,6 +197,7 @@ class EPLoginInputView: UIView { } private func setupCodeButton() { + codeButton.translatesAutoresizingMaskIntoConstraints = false codeButton.setTitle(YMLocalizedString("XPLoginInputView0"), for: .normal) codeButton.setTitleColor(.white, for: .normal) codeButton.titleLabel?.font = .systemFont(ofSize: 12, weight: .medium) diff --git a/YuMi/E-P/NewMine/Controllers/EPEditSettingViewController.swift b/YuMi/E-P/NewMine/Controllers/EPEditSettingViewController.swift index 1fefd74..6906eab 100644 --- a/YuMi/E-P/NewMine/Controllers/EPEditSettingViewController.swift +++ b/YuMi/E-P/NewMine/Controllers/EPEditSettingViewController.swift @@ -11,7 +11,7 @@ import SnapKit /// 设置编辑页面 /// 支持头像更新、昵称修改和退出登录功能 -class EPEditSettingViewController: UIViewController { +class EPEditSettingViewController: BaseViewController { // MARK: - UI Components private lazy var profileImageView: UIImageView = { @@ -317,19 +317,33 @@ class EPEditSettingViewController: UIViewController { } private func updateNickname(_ newNickname: String) { - // 构建UserInfoModel并调用更新方法 - let userInfo = UserInfoModel() - userInfo.nick = newNickname + // 显示加载状态 + showLoading() - // 调用Presenter方法 (桥接到OC) - let presenter = XPMineUserInfoEditPresenter() - presenter.getUserInfoEditDataSource(withUserInfo: userInfo) - - // 更新本地显示 - self.userInfo?.nick = newNickname - tableView.reloadData() - - print("[EPEditSetting] 昵称更新为: \(newNickname)") + // 调用 API 更新昵称 + apiHelper.updateNickname(withNick: newNickname, + completion: { [weak self] in + self?.hideHUD() + + // 更新成功后才更新本地显示 + self?.userInfo?.nick = newNickname + self?.tableView.reloadData() + + // 显示成功提示 + self?.showSuccessToast(YMLocalizedString("XPMineUserInfoEditViewController13")) + + print("[EPEditSetting] 昵称更新成功: \(newNickname)") + }, + failure: { [weak self] (code: Int, msg: String?) in + self?.hideHUD() + + // 显示错误提示 + let errorMsg = msg ?? "昵称更新失败,请稍后重试" + self?.showErrorToast(errorMsg) + + print("[EPEditSetting] 昵称更新失败: \(code) - \(errorMsg)") + } + ) } private func showLogoutConfirm() { diff --git a/YuMi/E-P/NewMine/Controllers/EPMineViewController.m b/YuMi/E-P/NewMine/Controllers/EPMineViewController.m index f92631f..618cefc 100644 --- a/YuMi/E-P/NewMine/Controllers/EPMineViewController.m +++ b/YuMi/E-P/NewMine/Controllers/EPMineViewController.m @@ -79,7 +79,7 @@ make.top.mas_equalTo(self.view); make.leading.mas_equalTo(self.view); make.trailing.mas_equalTo(self.view); - make.height.mas_equalTo(kGetScaleWidth(320)); + make.height.mas_equalTo(kGetScaleWidth(260)); }]; // 设置按钮点击回调 @@ -100,7 +100,6 @@ self.momentListView = [[EPMomentListView alloc] initWithFrame:CGRectZero]; [self.view addSubview:self.momentListView]; - // 使用 Masonry 约束布局 [self.momentListView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.headerView.mas_bottom); make.bottom.mas_equalTo(self.view); @@ -118,10 +117,10 @@ return; } - __weak typeof(self) weakSelf = self; - [self.apiHelper getUserDetailInfoWithUid:uid + @kWeakify(self); + [self.apiHelper getUserDetailInfoWithUid:uid completion:^(UserInfoModel * _Nullable userInfo) { - __strong typeof(weakSelf) self = weakSelf; + @kStrongify(self); if (!userInfo) { NSLog(@"[EPMineViewController] 加载用户信息失败"); return; diff --git a/YuMi/E-P/NewMine/Services/EPMineAPIHelper.h b/YuMi/E-P/NewMine/Services/EPMineAPIHelper.h index 8966727..c38d506 100644 --- a/YuMi/E-P/NewMine/Services/EPMineAPIHelper.h +++ b/YuMi/E-P/NewMine/Services/EPMineAPIHelper.h @@ -29,6 +29,11 @@ NS_ASSUME_NONNULL_BEGIN completion:(void (^)(void))completion failure:(void (^)(NSInteger code, NSString * _Nullable msg))failure; +/// 更新用户昵称 +- (void)updateNicknameWithNick:(NSString *)nickname + completion:(void (^)(void))completion + failure:(void (^)(NSInteger code, NSString * _Nullable msg))failure; + @end NS_ASSUME_NONNULL_END diff --git a/YuMi/E-P/NewMine/Services/EPMineAPIHelper.m b/YuMi/E-P/NewMine/Services/EPMineAPIHelper.m index dab86d2..148d9e2 100644 --- a/YuMi/E-P/NewMine/Services/EPMineAPIHelper.m +++ b/YuMi/E-P/NewMine/Services/EPMineAPIHelper.m @@ -9,6 +9,7 @@ #import "Api+Mine.h" #import "UserInfoModel.h" #import "BaseModel.h" +#import "AccountInfoStorage.h" @implementation EPMineAPIHelper @@ -50,5 +51,27 @@ } avatarUrl:avatarUrl needPay:@NO]; } +- (void)updateNicknameWithNick:(NSString *)nickname + completion:(void (^)(void))completion + failure:(void (^)(NSInteger code, NSString * _Nullable msg))failure { + NSString *uid = [[AccountInfoStorage instance] getUid]; + NSString *ticket = [[AccountInfoStorage instance] getTicket]; + + NSMutableDictionary *params = [NSMutableDictionary dictionary]; + if (nickname.length > 0) { + [params setValue:nickname forKey:@"nick"]; + } + [params setObject:uid forKey:@"uid"]; + [params setObject:ticket forKey:@"ticket"]; + + [Api completeUserInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { + if (code == 200) { + if (completion) completion(); + } else { + if (failure) failure(code, msg); + } + } userInfo:params]; +} + @end diff --git a/YuMi/E-P/NewMoments/Controllers/EPMomentPublishViewController.m b/YuMi/E-P/NewMoments/Controllers/EPMomentPublishViewController.m index 23520d5..bf8d92b 100644 --- a/YuMi/E-P/NewMoments/Controllers/EPMomentPublishViewController.m +++ b/YuMi/E-P/NewMoments/Controllers/EPMomentPublishViewController.m @@ -90,10 +90,16 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot make.leading.trailing.equalTo(self.textView); make.height.mas_equalTo(1); }]; + // 计算显示3行图片所需的高度 + // itemW = (屏幕宽度 - 左右边距30 - 列间距20) / 3 + // 总高度 = 3行itemW + 2个行间距(10*2) + CGFloat itemW = (KScreenWidth - 15*2 - 10*2)/3.0; + CGFloat collectionHeight = itemW * 3 + 10 * 2; + [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.equalTo(self.contentView).inset(15); make.top.equalTo(self.lineView.mas_bottom).offset(10); - make.height.mas_equalTo(110); + make.height.mas_equalTo(collectionHeight); }]; // 底部发布按钮 diff --git a/YuMi/E-P/NewMoments/Views/EPMomentCell.m b/YuMi/E-P/NewMoments/Views/EPMomentCell.m index d4674ce..f680169 100644 --- a/YuMi/E-P/NewMoments/Views/EPMomentCell.m +++ b/YuMi/E-P/NewMoments/Views/EPMomentCell.m @@ -120,7 +120,8 @@ make.leading.trailing.equalTo(self.cardView); make.top.equalTo(self.imagesContainer.mas_bottom).offset(12); make.height.mas_equalTo(50); - make.bottom.equalTo(self.cardView).offset(-8); + // 降低底部约束优先级,避免与图片容器高度冲突 + make.bottom.equalTo(self.cardView).offset(-8).priority(UILayoutPriorityDefaultHigh); }]; // 点赞按钮