feat: 添加设置编辑页面及相关功能
主要变更: 1. 新增 EPEditSettingViewController,提供用户头像更新、昵称修改和退出登录功能。 2. 在 Bridging Header 中引入 UserInfoModel、XPMineUserInfoEditPresenter 等新模块,以支持设置页面的功能。 3. 更新多语言文件,添加设置页面相关的本地化字符串。 此更新旨在提升用户体验,简化用户信息管理流程。
This commit is contained in:
522
YuMi/E-P/NewMine/Controllers/EPEditSettingViewController.swift
Normal file
522
YuMi/E-P/NewMine/Controllers/EPEditSettingViewController.swift
Normal file
@@ -0,0 +1,522 @@
|
||||
//
|
||||
// EPEditSettingViewController.swift
|
||||
// YuMi
|
||||
//
|
||||
// Created by AI on 2025-01-27.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Photos
|
||||
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.masksToBounds = true
|
||||
imageView.backgroundColor = .systemGray5
|
||||
imageView.isUserInteractionEnabled = true
|
||||
return imageView
|
||||
}()
|
||||
|
||||
// MARK: - Data
|
||||
|
||||
private var settingItems: [SettingItem] = []
|
||||
private var userInfo: UserInfoModel?
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
navigationController?.setNavigationBarHidden(true, animated: false)
|
||||
setupUI()
|
||||
setupData()
|
||||
loadUserInfo()
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
private func setupUI() {
|
||||
view.backgroundColor = UIColor(hex: "#0C0527")
|
||||
title = YMLocalizedString("EPEditSetting.Title")
|
||||
|
||||
view.addSubview(tableView)
|
||||
tableView.snp.makeConstraints { make in
|
||||
make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
|
||||
make.leading.trailing.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
// 添加头像点击手势
|
||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(profileImageTapped))
|
||||
profileImageView.addGestureRecognizer(tapGesture)
|
||||
}
|
||||
|
||||
private func setupData() {
|
||||
settingItems = [
|
||||
SettingItem(
|
||||
title: YMLocalizedString("EPEditSetting.PersonalInfo"),
|
||||
action: { [weak self] in self?.handleReservedAction("PersonalInfo") }
|
||||
),
|
||||
SettingItem(
|
||||
title: YMLocalizedString("EPEditSetting.Help"),
|
||||
action: { [weak self] in self?.handleReservedAction("Help") }
|
||||
),
|
||||
SettingItem(
|
||||
title: YMLocalizedString("EPEditSetting.ClearCache"),
|
||||
action: { [weak self] in self?.handleReservedAction("ClearCache") }
|
||||
),
|
||||
SettingItem(
|
||||
title: YMLocalizedString("EPEditSetting.CheckUpdate"),
|
||||
action: { [weak self] in self?.handleReservedAction("CheckUpdate") }
|
||||
),
|
||||
SettingItem(
|
||||
title: YMLocalizedString("EPEditSetting.Logout"),
|
||||
style: .default,
|
||||
action: { [weak self] in self?.showLogoutConfirm() }
|
||||
),
|
||||
SettingItem(
|
||||
title: YMLocalizedString("EPEditSetting.AboutUs"),
|
||||
action: { [weak self] in self?.handleReservedAction("AboutUs") }
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
private func loadUserInfo() {
|
||||
// 获取当前用户信息
|
||||
guard let uid = AccountInfoStorage.instance().getUid(), !uid.isEmpty else {
|
||||
print("[EPEditSetting] 未登录,无法获取用户信息")
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 调用API获取用户详细信息
|
||||
// 这里暂时创建默认的UserInfoModel用于显示
|
||||
let tempUserInfo = UserInfoModel()
|
||||
tempUserInfo.nick = "User"
|
||||
tempUserInfo.avatar = ""
|
||||
userInfo = tempUserInfo
|
||||
|
||||
updateProfileImage()
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
private func updateProfileImage() {
|
||||
guard let avatarUrl = userInfo?.avatar, !avatarUrl.isEmpty else {
|
||||
profileImageView.image = UIImage(systemName: "person.circle.fill")
|
||||
return
|
||||
}
|
||||
|
||||
// 使用SDWebImage加载头像
|
||||
if let url = URL(string: avatarUrl) {
|
||||
profileImageView.sd_setImage(with: url, placeholderImage: UIImage(systemName: "person.circle.fill"))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func profileImageTapped() {
|
||||
showAvatarSelectionSheet()
|
||||
}
|
||||
|
||||
@objc private func openSettings() {
|
||||
// 预留设置按钮功能
|
||||
handleReservedAction("Settings")
|
||||
}
|
||||
|
||||
private func showAvatarSelectionSheet() {
|
||||
let alert = UIAlertController(title: YMLocalizedString("EPEditSetting.EditNickname"), message: nil, preferredStyle: .actionSheet)
|
||||
|
||||
// 拍照选项
|
||||
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()
|
||||
})
|
||||
|
||||
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Cancel"), style: .cancel))
|
||||
|
||||
// iPad支持
|
||||
if let popover = alert.popoverPresentationController {
|
||||
popover.sourceView = profileImageView
|
||||
popover.sourceRect = profileImageView.bounds
|
||||
}
|
||||
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
private func checkCameraPermissionAndPresent() {
|
||||
YYUtility.checkCameraAvailable { [weak self] in
|
||||
self?.presentImagePicker(sourceType: .camera)
|
||||
} denied: { [weak self] in
|
||||
self?.showPermissionAlert(title: "Camera Access", message: "Please allow camera access in Settings")
|
||||
} restriction: { [weak self] in
|
||||
self?.showPermissionAlert(title: "Camera Restricted", message: "Camera access is restricted on this device")
|
||||
}
|
||||
}
|
||||
|
||||
private func checkPhotoLibraryPermissionAndPresent() {
|
||||
YYUtility.checkAssetsLibrayAvailable { [weak self] in
|
||||
self?.presentImagePicker(sourceType: .photoLibrary)
|
||||
} denied: { [weak self] in
|
||||
self?.showPermissionAlert(title: "Photo Library Access", message: "Please allow photo library access in Settings")
|
||||
} restriction: { [weak self] in
|
||||
self?.showPermissionAlert(title: "Photo Library Restricted", message: "Photo library access is restricted on this device")
|
||||
}
|
||||
}
|
||||
|
||||
private func presentImagePicker(sourceType: UIImagePickerController.SourceType) {
|
||||
let imagePicker = UIImagePickerController()
|
||||
imagePicker.delegate = self
|
||||
imagePicker.sourceType = sourceType
|
||||
imagePicker.allowsEditing = true
|
||||
present(imagePicker, animated: true)
|
||||
}
|
||||
|
||||
private func showPermissionAlert(title: String, message: String) {
|
||||
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
|
||||
if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
|
||||
UIApplication.shared.open(settingsURL)
|
||||
}
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Cancel"), style: .cancel))
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
private func showNicknameEditAlert() {
|
||||
let alert = UIAlertController(
|
||||
title: YMLocalizedString("EPEditSetting.EditNickname"),
|
||||
message: nil,
|
||||
preferredStyle: .alert
|
||||
)
|
||||
|
||||
alert.addTextField { [weak self] textField in
|
||||
textField.text = self?.userInfo?.nick ?? ""
|
||||
textField.placeholder = YMLocalizedString("EPEditSetting.EnterNickname")
|
||||
}
|
||||
|
||||
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Cancel"), style: .cancel))
|
||||
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Confirm"), style: .default) { [weak self] _ in
|
||||
guard let newNickname = alert.textFields?.first?.text, !newNickname.isEmpty else { return }
|
||||
self?.updateNickname(newNickname)
|
||||
})
|
||||
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
private func updateNickname(_ newNickname: String) {
|
||||
// 构建UserInfoModel并调用更新方法
|
||||
let userInfo = UserInfoModel()
|
||||
userInfo.nick = newNickname
|
||||
|
||||
// 调用Presenter方法 (桥接到OC)
|
||||
let presenter = XPMineUserInfoEditPresenter()
|
||||
presenter.getUserInfoEditDataSource(withUserInfo: userInfo)
|
||||
|
||||
// 更新本地显示
|
||||
self.userInfo?.nick = newNickname
|
||||
tableView.reloadData()
|
||||
|
||||
print("[EPEditSetting] 昵称更新为: \(newNickname)")
|
||||
}
|
||||
|
||||
private func showLogoutConfirm() {
|
||||
let alert = UIAlertController(
|
||||
title: YMLocalizedString("EPEditSetting.LogoutConfirm"),
|
||||
message: nil,
|
||||
preferredStyle: .alert
|
||||
)
|
||||
|
||||
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Cancel"), style: .cancel))
|
||||
alert.addAction(UIAlertAction(title: YMLocalizedString("EPEditSetting.Logout"), style: .destructive) { [weak self] _ in
|
||||
self?.performLogout()
|
||||
})
|
||||
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
private func performLogout() {
|
||||
guard let account = AccountInfoStorage.instance().accountModel else {
|
||||
print("[EPEditSetting] 账号信息不存在")
|
||||
return
|
||||
}
|
||||
|
||||
// 调用登出API
|
||||
Api.logoutCurrentAccount({ [weak self] (data, code, msg) in
|
||||
DispatchQueue.main.async {
|
||||
// 清除本地数据
|
||||
AccountInfoStorage.instance().saveAccountInfo(nil)
|
||||
AccountInfoStorage.instance().saveTicket(nil)
|
||||
|
||||
// 跳转登录页
|
||||
self?.navigateToLogin()
|
||||
}
|
||||
}, access_token: account.access_token)
|
||||
}
|
||||
|
||||
private func navigateToLogin() {
|
||||
let loginVC = EPLoginViewController()
|
||||
let nav = UINavigationController(rootViewController: loginVC)
|
||||
|
||||
if let window = UIApplication.shared.windows.first {
|
||||
window.rootViewController = nav
|
||||
window.makeKeyAndVisible()
|
||||
}
|
||||
|
||||
print("[EPEditSetting] 已跳转到登录页面")
|
||||
}
|
||||
|
||||
private func handleReservedAction(_ title: String) {
|
||||
print("[\(title)] - 功能预留,待后续实现")
|
||||
// TODO: Phase 2 implementation
|
||||
|
||||
// 显示占位提示
|
||||
let alert = UIAlertController(title: "Coming Soon", message: "This feature will be available in the next update.", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .default))
|
||||
present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDataSource & UITableViewDelegate
|
||||
|
||||
extension EPEditSettingViewController: UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 2 // 头像昵称section + 设置项section
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
if section == 0 {
|
||||
return 2 // 头像 + 昵称
|
||||
} else {
|
||||
return settingItems.count
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingCell", for: indexPath)
|
||||
cell.backgroundColor = UIColor(hex: "#0C0527")
|
||||
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
|
||||
}
|
||||
} else {
|
||||
// 设置项section
|
||||
let item = settingItems[indexPath.row]
|
||||
cell.textLabel?.text = item.title
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
|
||||
if item.style == .default {
|
||||
cell.textLabel?.textColor = .systemRed
|
||||
} else {
|
||||
cell.textLabel?.textColor = .white
|
||||
}
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
if indexPath.section == 0 && indexPath.row == 0 {
|
||||
return 120 // 头像行更高
|
||||
}
|
||||
return 60
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
if indexPath.section == 0 {
|
||||
if indexPath.row == 0 {
|
||||
// 头像点击
|
||||
showAvatarSelectionSheet()
|
||||
} else {
|
||||
// 昵称点击
|
||||
showNicknameEditAlert()
|
||||
}
|
||||
} else {
|
||||
// 设置项点击
|
||||
let item = settingItems[indexPath.row]
|
||||
item.action()
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return section == 0 ? 20 : 10
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
let view = UIView()
|
||||
view.backgroundColor = UIColor(hex: "#0C0527")
|
||||
return view
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
|
||||
return 10
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
|
||||
let view = UIView()
|
||||
view.backgroundColor = UIColor(hex: "#0C0527")
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate
|
||||
|
||||
extension EPEditSettingViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
||||
|
||||
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
|
||||
picker.dismiss(animated: true)
|
||||
|
||||
guard let image = info[.editedImage] as? UIImage ?? info[.originalImage] as? UIImage else {
|
||||
print("[EPEditSetting] 未能获取选择的图片")
|
||||
return
|
||||
}
|
||||
|
||||
// 更新头像显示
|
||||
profileImageView.image = image
|
||||
|
||||
// 上传头像到腾讯云
|
||||
uploadAvatar(image)
|
||||
}
|
||||
|
||||
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
||||
picker.dismiss(animated: true)
|
||||
}
|
||||
|
||||
private func uploadAvatar(_ image: UIImage) {
|
||||
// 压缩图片
|
||||
guard let imageData = image.jpegData(compressionQuality: 0.5) else {
|
||||
print("[EPEditSetting] 图片压缩失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成文件名
|
||||
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)")
|
||||
})
|
||||
}
|
||||
|
||||
private func updateAvatarAPI(avatarUrl: String) {
|
||||
// 调用API更新头像
|
||||
Api.userV2UploadAvatar({ [weak self] (data, code, msg) in
|
||||
DispatchQueue.main.async {
|
||||
if code == 200 {
|
||||
print("[EPEditSetting] 头像更新成功")
|
||||
// 更新本地用户信息
|
||||
self?.userInfo?.avatar = avatarUrl
|
||||
} else {
|
||||
print("[EPEditSetting] 头像更新失败: \(String(describing: msg))")
|
||||
}
|
||||
}
|
||||
}, avatarUrl: avatarUrl, needPay: NSNumber(value: false))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helper Models
|
||||
|
||||
private struct SettingItem {
|
||||
let title: String
|
||||
let style: UITableViewCell.SelectionStyle
|
||||
let action: () -> Void
|
||||
|
||||
init(title: String, style: UITableViewCell.SelectionStyle = .default, action: @escaping () -> Void) {
|
||||
self.title = title
|
||||
self.style = style
|
||||
self.action = action
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIColor Extension
|
||||
|
||||
private extension UIColor {
|
||||
convenience init(hex: String) {
|
||||
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
|
||||
var int: UInt64 = 0
|
||||
Scanner(string: hex).scanHexInt64(&int)
|
||||
let a, r, g, b: UInt64
|
||||
switch hex.count {
|
||||
case 3: // RGB (12-bit)
|
||||
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
|
||||
case 6: // RGB (24-bit)
|
||||
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
|
||||
case 8: // ARGB (32-bit)
|
||||
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
|
||||
default:
|
||||
(a, r, g, b) = (1, 1, 1, 0)
|
||||
}
|
||||
|
||||
self.init(
|
||||
red: CGFloat(r) / 255,
|
||||
green: CGFloat(g) / 255,
|
||||
blue: CGFloat(b) / 255,
|
||||
alpha: CGFloat(a) / 255
|
||||
)
|
||||
}
|
||||
}
|
@@ -12,6 +12,8 @@
|
||||
#import "EPMineAPIHelper.h"
|
||||
#import "AccountInfoStorage.h"
|
||||
#import "UserInfoModel.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
#import "YuMi-Swift.h" // 导入Swift桥接
|
||||
|
||||
@interface EPMineViewController ()
|
||||
|
||||
@@ -42,7 +44,7 @@
|
||||
|
||||
[self setupUI];
|
||||
|
||||
NSLog(@"[EPMineViewController] 个人主页加载完成");
|
||||
NSLog(@"[EPMineViewController] viewDidLoad 完成");
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
@@ -56,17 +58,10 @@
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
- (void)setupUI {
|
||||
// 先设置纯色背景作为兜底,避免白色闪烁
|
||||
self.view.backgroundColor = [UIColor clearColor];
|
||||
|
||||
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:kImage(@"vc_bg")];
|
||||
bgImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
bgImageView.clipsToBounds = YES;
|
||||
[self.view addSubview:bgImageView];
|
||||
[bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self.view);
|
||||
}];
|
||||
// 背景渐变色
|
||||
self.view.backgroundColor = [UIColor colorWithRed:0.047 green:0.020 blue:0.153 alpha:1.0]; // #0C0527
|
||||
|
||||
[self setupHeaderView];
|
||||
[self setupMomentListView];
|
||||
@@ -75,76 +70,88 @@
|
||||
}
|
||||
|
||||
- (void)setupHeaderView {
|
||||
self.headerView = [[EPMineHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 300)];
|
||||
|
||||
self.headerView = [[EPMineHeaderView alloc] initWithFrame:CGRectZero];
|
||||
[self.view addSubview:self.headerView];
|
||||
|
||||
[self.headerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(self.view).offset(20);
|
||||
make.leading.trailing.equalTo(self.view);
|
||||
make.height.equalTo(@300);
|
||||
}];
|
||||
// 使用约束布局
|
||||
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[self.headerView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
|
||||
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
||||
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
||||
[self.headerView.heightAnchor constraintEqualToConstant:320]
|
||||
]];
|
||||
|
||||
// 监听设置按钮点击事件
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(openSettings)
|
||||
name:@"EPMineHeaderSettingsButtonTapped"
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)setupMomentListView {
|
||||
self.momentListView = [[EPMomentListView alloc] initWithFrame:CGRectZero];
|
||||
[self.view addSubview:self.momentListView];
|
||||
|
||||
[self.momentListView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(self.headerView.mas_bottom).offset(10);
|
||||
make.leading.trailing.bottom.equalTo(self.view);
|
||||
}];
|
||||
// 使用约束布局
|
||||
self.momentListView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[self.momentListView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor],
|
||||
[self.momentListView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
||||
[self.momentListView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
||||
[self.momentListView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
|
||||
]];
|
||||
}
|
||||
|
||||
// MARK: - Data Loading
|
||||
|
||||
- (void)loadUserDetailInfo {
|
||||
NSString *uid = [[AccountInfoStorage instance] getUid];
|
||||
if (!uid.length) {
|
||||
NSLog(@"[EPMineViewController] 未登录,无法获取用户信息");
|
||||
if (!uid || uid.length == 0) {
|
||||
NSLog(@"[EPMineViewController] 用户未登录");
|
||||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self.apiHelper getUserDetailInfoWithUid:uid completion:^(UserInfoModel * _Nullable userInfo) {
|
||||
[self.apiHelper getUserDetailInfoWithUid:uid
|
||||
completion:^(UserInfoModel * _Nullable userInfo) {
|
||||
__strong typeof(weakSelf) self = weakSelf;
|
||||
if (!userInfo) {
|
||||
NSLog(@"[EPMineViewController] 加载用户信息失败");
|
||||
return;
|
||||
}
|
||||
|
||||
self.userInfo = userInfo;
|
||||
[self updateHeaderWithUserInfo:userInfo];
|
||||
|
||||
// 更新头部视图
|
||||
NSDictionary *userInfoDict = @{
|
||||
@"nickname": userInfo.nick ?: @"未设置昵称",
|
||||
@"avatar": userInfo.avatar ?: @"",
|
||||
@"uid": userInfo.uid > 0 ? @(userInfo.uid).stringValue : @"",
|
||||
@"followers": @(userInfo.fansNum),
|
||||
@"following": @(userInfo.followNum),
|
||||
};
|
||||
[self.headerView updateWithUserInfo:userInfoDict];
|
||||
|
||||
// 使用本地数组模式显示用户动态
|
||||
[self.momentListView loadWithDynamicInfo:userInfo.dynamicInfo refreshCallback:^{
|
||||
[self loadUserDetailInfo];
|
||||
}];
|
||||
|
||||
NSLog(@"[EPMineViewController] 用户详情加载成功: %@ (动态数: %lu)",
|
||||
userInfo.nick, (unsigned long)userInfo.dynamicInfo.count);
|
||||
|
||||
// 如果有动态信息,直接使用
|
||||
if (userInfo.dynamicInfo && userInfo.dynamicInfo.count > 0) {
|
||||
[self.momentListView loadWithDynamicInfo:userInfo.dynamicInfo refreshCallback:^{
|
||||
[self loadUserDetailInfo]; // 刷新时重新加载
|
||||
}];
|
||||
}
|
||||
} failure:^(NSInteger code, NSString * _Nullable msg) {
|
||||
NSLog(@"[EPMineViewController] 用户详情加载失败: code=%ld, msg=%@", (long)code, msg);
|
||||
NSLog(@"[EPMineViewController] 加载用户信息失败: %@", msg);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateHeaderWithUserInfo:(UserInfoModel *)userInfo {
|
||||
NSDictionary *userInfoDict = @{
|
||||
@"nickname": userInfo.nick ?: @"未设置昵称",
|
||||
@"uid": [NSString stringWithFormat:@"%ld", (long)userInfo.uid],
|
||||
@"avatar": userInfo.avatar ?: @"",
|
||||
@"following": @(userInfo.followNum),
|
||||
@"followers": @(userInfo.fansNum)
|
||||
};
|
||||
|
||||
[self.headerView updateWithUserInfo:userInfoDict];
|
||||
}
|
||||
|
||||
// MARK: - Lazy Loading
|
||||
|
||||
- (EPMineHeaderView *)headerView {
|
||||
if (!_headerView) {
|
||||
_headerView = [[EPMineHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 300)];
|
||||
}
|
||||
return _headerView;
|
||||
}
|
||||
|
||||
- (EPMomentListView *)momentListView {
|
||||
if (!_momentListView) {
|
||||
_momentListView = [[EPMomentListView alloc] initWithFrame:CGRectZero];
|
||||
|
||||
_momentListView = [[EPMomentListView alloc] init];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
_momentListView.onSelectMoment = ^(NSInteger index) {
|
||||
__strong typeof(weakSelf) self = weakSelf;
|
||||
@@ -162,4 +169,16 @@
|
||||
return _apiHelper;
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
- (void)openSettings {
|
||||
EPEditSettingViewController *settingsVC = [[EPEditSettingViewController alloc] init];
|
||||
[self.navigationController pushViewController:settingsVC animated:YES];
|
||||
NSLog(@"[EPMineViewController] 打开设置页面");
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -159,7 +159,8 @@
|
||||
|
||||
- (void)settingsButtonTapped {
|
||||
NSLog(@"[EPMineHeaderView] 设置按钮点击");
|
||||
// TODO: 发送通知或回调给父视图
|
||||
// 发送通知给父视图
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"EPMineHeaderSettingsButtonTapped" object:nil];
|
||||
}
|
||||
|
||||
@end
|
@@ -39,6 +39,11 @@
|
||||
#import "AccountInfoStorage.h"
|
||||
#import "MomentsInfoModel.h"
|
||||
#import "MomentsListInfoModel.h"
|
||||
#import "UserInfoModel.h"
|
||||
#import "XPMineUserInfoEditPresenter.h"
|
||||
#import "UploadFile.h"
|
||||
#import "YYUtility.h"
|
||||
#import "SDWebImage.h"
|
||||
|
||||
// MARK: - Utilities
|
||||
#import "UIImage+Utils.h"
|
||||
|
@@ -4256,3 +4256,23 @@ ineHeadView12" = "الحمل";
|
||||
"20.20.62_text_22" = "لقد شغّلت شاشة ميكروفون CP.";
|
||||
"20.20.62_text_23" = "لقد أوقفت شاشة ميكروفون CP. شاشة ميكروفون CP غير مرئية في هذه الغرفة. انقر لتفعيلها مرة أخرى.";
|
||||
"20.20.62_text_24" = "لقد أوقفت وضع التربو.";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
|
@@ -4046,3 +4046,23 @@
|
||||
"20.20.62_text_22" = "You have turn on the CP Mic Display.";
|
||||
"20.20.62_text_23" = "You have turn off the CP Mic Display. The CP Mic Display is not visible in this room. Click to enable it again.";
|
||||
"20.20.62_text_24" = "You have turned off Turbo Mode.";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
|
@@ -3717,6 +3717,26 @@
|
||||
"RoomBoom_5" = "Nombre de la sala:";//"Room name:";
|
||||
"RoomBoom_6" = "Hora de reinicio: 0:00 (GMT+3) diariamente";
|
||||
"RoomBoom_7" = " Clasificación de Colaboradores";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
"RoomBoom_8" = "Super Jackpot";
|
||||
"RoomBoom_9" = "Reset time: 0:00 (GMT+8) daily";
|
||||
"RoomBoom_10" = "The rewards are for reference only. The specific gifts are determined by your contribution value and luck.";
|
||||
|
@@ -3337,3 +3337,23 @@
|
||||
"20.20.62_text_22" = "Você ativou a Exibição do Microfone CP.";
|
||||
"20.20.62_text_23" = "Você desativou a Exibição do Microfone CP. A Exibição do Microfone CP não está visível nesta sala. Clique para ativá-la novamente.";
|
||||
"20.20.62_text_24" = "Você desativou o Modo Turbo.";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
|
@@ -3716,6 +3716,26 @@
|
||||
"RoomBoom_5" = "";//"Название комнаты:";
|
||||
"RoomBoom_6" = "Время сброса: 0:00 (GMT+3) ежедневно";
|
||||
"RoomBoom_7" = " Рейтинг спонсоров";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
"RoomBoom_8" = "Супер джекпот";
|
||||
"RoomBoom_9" = "Время сброса: 0:00 (GMT+8) ежедневно";
|
||||
"RoomBoom_10" = "Награды приведены для справки. Конкретные подарки определяются вашим вкладом и удачей.";
|
||||
|
@@ -3837,3 +3837,23 @@
|
||||
"20.20.62_text_22" = "CP Mikrofon Ekranını açtınız.";
|
||||
"20.20.62_text_23" = "CP Mikrofon Ekranını kapattınız. CP Mikrofon Ekranı bu odada görünmüyor. Tekrar etkinleştirmek için tıklayın.";
|
||||
"20.20.62_text_24" = "Turbo Modu'nu kapattınız.";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
|
@@ -3717,6 +3717,26 @@ Tasdiqlangandan so'ng, sekretar sizga uni chop etishda yordam beradi va sizni xa
|
||||
"1.0.18_1" = "Bepul";
|
||||
"1.0.18_2" = "Pay";
|
||||
"1.0.18_3" = "Maxsus";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
"1.0.18_4" = "Yangi yaratish";
|
||||
"1.0.18_5" = "Siz maksimal 6 ta fonni moslashtirishingiz mumkin.";
|
||||
"1.0.18_6" = "Maxsus fon sifatida bir vaqtning o'zida maksimal 6 ta rasm yuklashingiz mumkin. \nFon yaratilgandan so'ng, uni bekor qilib bo'lmaydi. \nYuklangan fonni 24 soat ichida tekshiramiz. \nAgar fon rad etilsa, sizga tangalarni qaytarib beramiz.";
|
||||
|
@@ -3707,3 +3707,23 @@
|
||||
"20.20.62_text_22" = "您已開啟 CP 麥克風顯示。";
|
||||
"20.20.62_text_23" = "您已關閉 CP 麥克風顯示。此房間中不顯示 CP 麥克風顯示。點選可重新啟用。";
|
||||
"20.20.62_text_24" = "您已關閉 Turbo 模式。";
|
||||
|
||||
// EPEditSetting - 设置页面多语言Key
|
||||
"EPEditSetting.Title" = "Edit";
|
||||
"EPEditSetting.Avatar" = "Avatar";
|
||||
"EPEditSetting.Nickname" = "Nickname";
|
||||
"EPEditSetting.PersonalInfo" = "Personal Information and Permissions";
|
||||
"EPEditSetting.Help" = "Help";
|
||||
"EPEditSetting.ClearCache" = "Clear Cache";
|
||||
"EPEditSetting.CheckUpdate" = "Check for Updates";
|
||||
"EPEditSetting.AboutUs" = "About Us";
|
||||
"EPEditSetting.Logout" = "Log out of account";
|
||||
|
||||
// Alert
|
||||
"EPEditSetting.Camera" = "Take Photo";
|
||||
"EPEditSetting.PhotoLibrary" = "Choose from Album";
|
||||
"EPEditSetting.EditNickname" = "Edit Nickname";
|
||||
"EPEditSetting.EnterNickname" = "Enter new nickname";
|
||||
"EPEditSetting.LogoutConfirm" = "Are you sure you want to log out?";
|
||||
"EPEditSetting.Cancel" = "Cancel";
|
||||
"EPEditSetting.Confirm" = "Confirm";
|
||||
|
Reference in New Issue
Block a user