feat: 更新 EPEditSettingViewController 以增强用户信息管理功能

主要变更:
1. 在 EPEditSettingViewController 中添加了用户头像和相机图标的布局,提升用户界面友好性。
2. 引入 EPMineAPIHelper 以支持头像更新功能,简化 API 调用。
3. 优化了导航栏的显示和隐藏逻辑,确保用户体验流畅。
4. 更新了 UITableView 的数据源和布局,确保信息展示清晰。

此更新旨在提升用户体验,简化用户信息的管理和更新流程。
This commit is contained in:
edwinQQQ
2025-10-14 14:46:08 +08:00
parent e4f4557369
commit 955cc3622f
13 changed files with 392 additions and 279 deletions

View File

@@ -12,39 +12,50 @@ import SnapKit
///
/// 退
class EPEditSettingViewController: UIViewController {
// MARK: - UI Components
private lazy var tableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .grouped)
tableView.backgroundColor = UIColor(hex: "#0C0527")
tableView.separatorStyle = .none
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "SettingCell")
return tableView
}()
private lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = 50
imageView.layer.cornerRadius = 60 // 120/2 = 60
imageView.layer.masksToBounds = true
imageView.backgroundColor = .systemGray5
imageView.isUserInteractionEnabled = true
return imageView
}()
private lazy var cameraIconView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.image = UIImage(named: "icon_setting_camear")
imageView.backgroundColor = UIColor(hex: "#0C0527")
imageView.layer.cornerRadius = 15 // 30/2 = 15
imageView.layer.masksToBounds = true
return imageView
}()
private lazy var tableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .plain)
tableView.backgroundColor = UIColor(hex: "#0C0527")
tableView.separatorStyle = .none
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "SettingCell")
tableView.isScrollEnabled = true //
return tableView
}()
// MARK: - Data
private var settingItems: [SettingItem] = []
private var userInfo: UserInfoModel?
private var apiHelper: EPMineAPIHelper = EPMineAPIHelper()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
setupNavigationBar()
setupUI()
setupData()
loadUserInfo()
@@ -52,35 +63,96 @@ class EPEditSettingViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//
navigationController?.setNavigationBarHidden(false, animated: animated)
navigationController?.navigationBar.titleTextAttributes = [
.foregroundColor: UIColor.white,
.font: UIFont.systemFont(ofSize: 18, weight: .medium)
]
navigationController?.navigationBar.barTintColor = UIColor(hex: "#0C0527")
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.isTranslucent = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//
restoreParentNavigationBarStyle()
}
// MARK: - Setup
private func setupUI() {
view.backgroundColor = UIColor(hex: "#0C0527")
private func setupNavigationBar() {
title = YMLocalizedString("EPEditSetting.Title")
// iOS 13+
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = UIColor(hex: "#0C0527")
appearance.titleTextAttributes = [
.foregroundColor: UIColor.white,
.font: UIFont.systemFont(ofSize: 18, weight: .medium)
]
appearance.shadowColor = .clear // 线
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
navigationController?.navigationBar.compactAppearance = appearance
navigationController?.navigationBar.tintColor = .white //
//
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
// push backButtonTitle
navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(
title: "",
style: .plain,
target: nil,
action: nil
)
}
private func restoreParentNavigationBarStyle() {
// EPMineViewController 使
let transparentAppearance = UINavigationBarAppearance()
transparentAppearance.configureWithTransparentBackground()
transparentAppearance.backgroundColor = .clear
transparentAppearance.shadowColor = .clear
navigationController?.navigationBar.standardAppearance = transparentAppearance
navigationController?.navigationBar.scrollEdgeAppearance = transparentAppearance
navigationController?.navigationBar.compactAppearance = transparentAppearance
}
private func setupUI() {
view.backgroundColor = UIColor(hex: "#0C0527")
//
view.addSubview(profileImageView)
profileImageView.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(40)
make.centerX.equalTo(view)
make.size.equalTo(120)
}
//
view.addSubview(cameraIconView)
cameraIconView.snp.makeConstraints { make in
make.bottom.equalTo(profileImageView.snp.bottom)
make.trailing.equalTo(profileImageView.snp.trailing)
make.size.equalTo(30)
}
// TableView
view.addSubview(tableView)
tableView.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
make.leading.trailing.bottom.equalToSuperview()
make.top.equalTo(profileImageView.snp.bottom).offset(40)
make.leading.trailing.bottom.equalTo(view)
}
//
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(profileImageTapped))
profileImageView.addGestureRecognizer(tapGesture)
//
let cameraTapGesture = UITapGestureRecognizer(target: self, action: #selector(profileImageTapped))
cameraIconView.addGestureRecognizer(cameraTapGesture)
}
private func setupData() {
settingItems = [
SettingItem(
@@ -109,9 +181,17 @@ class EPEditSettingViewController: UIViewController {
action: { [weak self] in self?.handleReservedAction("AboutUs") }
)
]
NSLog("[EPEditSetting] setupData 完成,设置项数量: \(settingItems.count)")
}
private func loadUserInfo() {
// EPMineViewController
if userInfo != nil {
updateProfileImage()
tableView.reloadData()
return
}
//
guard let uid = AccountInfoStorage.instance().getUid(), !uid.isEmpty else {
print("[EPEditSetting] 未登录,无法获取用户信息")
@@ -159,7 +239,7 @@ class EPEditSettingViewController: UIViewController {
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Camera"), style: .default) { [weak self] _ in
self?.checkCameraPermissionAndPresent()
})
//
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.PhotoLibrary"), style: .default) { [weak self] _ in
self?.checkPhotoLibraryPermissionAndPresent()
@@ -307,6 +387,16 @@ class EPEditSettingViewController: UIViewController {
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
// MARK: - Public Methods
/// EPMineViewController
@objc func updateWithUserInfo(_ userInfo: UserInfoModel) {
self.userInfo = userInfo
updateProfileImage()
tableView.reloadData()
NSLog("[EPEditSetting] 已更新用户信息: \(userInfo.nick ?? "未知")")
}
}
// MARK: - UITableViewDataSource & UITableViewDelegate
@@ -314,15 +404,13 @@ class EPEditSettingViewController: UIViewController {
extension EPEditSettingViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 2 // section + section
return 1 // section
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 2 // +
} else {
return settingItems.count
}
let count = settingItems.count + 1 // +1 for nickname row
NSLog("[EPEditSetting] TableView rows count: \(count), settingItems: \(settingItems.count)")
return count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -331,35 +419,50 @@ extension EPEditSettingViewController: UITableViewDataSource, UITableViewDelegat
cell.textLabel?.textColor = .white
cell.selectionStyle = .none
if indexPath.section == 0 {
// section
if indexPath.row == 0 {
//
cell.textLabel?.text = YMLocalizedString("EPEditSetting.Avatar")
cell.accessoryType = .disclosureIndicator
//
if cell.contentView.subviews.contains(profileImageView) {
profileImageView.removeFromSuperview()
}
cell.contentView.addSubview(profileImageView)
profileImageView.snp.makeConstraints { make in
make.trailing.equalToSuperview().offset(-50)
make.centerY.equalToSuperview()
make.size.equalTo(100)
}
} else {
//
cell.textLabel?.text = YMLocalizedString("EPEditSetting.Nickname")
cell.detailTextLabel?.text = userInfo?.nick ?? "未设置"
cell.detailTextLabel?.textColor = .lightGray
cell.accessoryType = .disclosureIndicator
//
cell.contentView.subviews.forEach { $0.removeFromSuperview() }
if indexPath.row == 0 {
//
cell.textLabel?.text = YMLocalizedString("EPEditSetting.Nickname")
//
let arrowImageView = UIImageView()
arrowImageView.image = UIImage(named: "icon_setting_right_arrow")
arrowImageView.contentMode = .scaleAspectFit
cell.contentView.addSubview(arrowImageView)
arrowImageView.snp.makeConstraints { make in
make.trailing.equalToSuperview().offset(-20)
make.centerY.equalToSuperview()
make.size.equalTo(22)
}
//
let nicknameLabel = UILabel()
nicknameLabel.text = userInfo?.nick ?? "未设置"
nicknameLabel.textColor = .lightGray
nicknameLabel.font = UIFont.systemFont(ofSize: 16)
cell.contentView.addSubview(nicknameLabel)
nicknameLabel.snp.makeConstraints { make in
make.trailing.equalTo(arrowImageView.snp.leading).offset(-12)
make.centerY.equalToSuperview()
}
} else {
// section
let item = settingItems[indexPath.row]
//
let item = settingItems[indexPath.row - 1]
cell.textLabel?.text = item.title
cell.accessoryType = .disclosureIndicator
//
let arrowImageView = UIImageView()
arrowImageView.image = UIImage(named: "icon_setting_right_arrow")
arrowImageView.contentMode = .scaleAspectFit
cell.contentView.addSubview(arrowImageView)
arrowImageView.snp.makeConstraints { make in
make.trailing.equalToSuperview().offset(-20)
make.centerY.equalToSuperview()
make.size.equalTo(22)
}
if item.style == .default {
cell.textLabel?.textColor = .systemRed
@@ -372,48 +475,36 @@ extension EPEditSettingViewController: UITableViewDataSource, UITableViewDelegat
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 && indexPath.row == 0 {
return 120 //
}
return 60
return 60 // 60pt
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if indexPath.section == 0 {
if indexPath.row == 0 {
//
showAvatarSelectionSheet()
} else {
//
showNicknameEditAlert()
}
if indexPath.row == 0 {
//
showNicknameEditAlert()
} else {
//
let item = settingItems[indexPath.row]
let item = settingItems[indexPath.row - 1]
item.action()
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? 20 : 10
return 0
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = UIColor(hex: "#0C0527")
return view
return nil
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 10
return 0
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = UIColor(hex: "#0C0527")
return view
return nil
}
}
@@ -441,41 +532,75 @@ extension EPEditSettingViewController: UIImagePickerControllerDelegate, UINaviga
}
private func uploadAvatar(_ image: UIImage) {
//
guard let imageData = image.jpegData(compressionQuality: 0.5) else {
print("[EPEditSetting] 图片压缩失败")
return
}
//
EPProgressHUD.showProgress(0, total: 1)
//
let format = "jpg"
let name = "image/\(UUID().uuidString).\(format)"
//
UploadFile.share().qCloudUploadImage(imageData, named: name, success: { [weak self] (key, resp) in
print("[EPEditSetting] 头像上传成功: \(key)")
// API
self?.updateAvatarAPI(avatarUrl: key)
}, failure: { (resCode, message) in
print("[EPEditSetting] 头像上传失败: \(message)")
})
// 使 EPSDKManager OCR
EPSDKManager.shared.uploadImages([image],
progress: { uploaded, total in
EPProgressHUD.showProgress(uploaded, total: total)
},
success: { [weak self] resList in
EPProgressHUD.dismiss()
guard !resList.isEmpty,
let firstRes = resList.first,
let avatarUrl = firstRes["resUrl"] as? String else {
print("[EPEditSetting] 头像上传成功但无法获取URL")
return
}
print("[EPEditSetting] 头像上传成功: \(avatarUrl)")
// API
self?.updateAvatarAPI(avatarUrl: avatarUrl)
},
failure: { [weak self] errorMsg in
EPProgressHUD.dismiss()
print("[EPEditSetting] 头像上传失败: \(errorMsg)")
//
DispatchQueue.main.async {
let alert = UIAlertController(title: "上传失败", message: errorMsg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "确定", style: .default))
self?.present(alert, animated: true)
}
}
)
}
private func updateAvatarAPI(avatarUrl: String) {
// API
Api.userV2UploadAvatar({ [weak self] (data, code, msg) in
// 使 API Helper
apiHelper.updateAvatar(withUrl: avatarUrl, completion: { [weak self] in
print("[EPEditSetting] 头像更新成功")
//
self?.userInfo?.avatar = avatarUrl
//
self?.notifyParentAvatarUpdated(avatarUrl)
}, failure: { [weak self] (code: Int, msg: String?) in
print("[EPEditSetting] 头像更新失败: \(code) - \(msg ?? "未知错误")")
//
DispatchQueue.main.async {
if code == 200 {
print("[EPEditSetting] 头像更新成功")
//
self?.userInfo?.avatar = avatarUrl
} else {
print("[EPEditSetting] 头像更新失败: \(String(describing: msg))")
}
let alert = UIAlertController(
title: "更新失败",
message: msg ?? "头像更新失败,请稍后重试",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "确定", style: .default))
self?.present(alert, animated: true)
}
}, avatarUrl: avatarUrl, needPay: NSNumber(value: false))
})
}
private func notifyParentAvatarUpdated(_ avatarUrl: String) {
// EPMineViewController
let userInfo = ["avatarUrl": avatarUrl]
NotificationCenter.default.post(name: NSNotification.Name("EPEditSettingAvatarUpdated"), object: nil, userInfo: userInfo)
}
}