|
|
@@ -38,6 +38,51 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
private let tagScroll = UIScrollView()
|
|
|
private let tagStack = UIStackView()
|
|
|
private let recordStack = UIStackView()
|
|
|
+
|
|
|
+ // 空视图组件
|
|
|
+ private lazy var emptyStateView: UIView = {
|
|
|
+ let container = UIView()
|
|
|
+ container.backgroundColor = .clear
|
|
|
+
|
|
|
+ let imageView = UIImageView()
|
|
|
+ imageView.image = UIImage(named: "emptydata") // 使用现有的图片资源
|
|
|
+ imageView.contentMode = .scaleAspectFit
|
|
|
+// imageView.tintColor = UIColor(hex: "#CFCFCF")
|
|
|
+
|
|
|
+ let titleLabel = UILabel()
|
|
|
+ titleLabel.text = "暂无记录"
|
|
|
+ titleLabel.font = .systemFont(ofSize: 18, weight: .medium)
|
|
|
+ titleLabel.textColor = UIColor(hex: "#CFCFCF")
|
|
|
+ titleLabel.textAlignment = .center
|
|
|
+
|
|
|
+ let subtitleLabel = UILabel()
|
|
|
+ subtitleLabel.text = "快去记录第一个美好时刻吧~"
|
|
|
+ subtitleLabel.font = .systemFont(ofSize: 14)
|
|
|
+ subtitleLabel.textColor = UIColor(hex: "#CFCFCF")
|
|
|
+ subtitleLabel.textAlignment = .center
|
|
|
+
|
|
|
+ let stackView = UIStackView(arrangedSubviews: [imageView, titleLabel, subtitleLabel])
|
|
|
+ stackView.axis = .vertical
|
|
|
+ stackView.alignment = .center
|
|
|
+ stackView.spacing = 16
|
|
|
+
|
|
|
+ container.addSubview(stackView)
|
|
|
+ stackView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ imageView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ imageView.widthAnchor.constraint(equalToConstant: 80),
|
|
|
+ imageView.heightAnchor.constraint(equalToConstant: 80),
|
|
|
+
|
|
|
+ stackView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
|
|
|
+ stackView.centerYAnchor.constraint(equalTo: container.centerYAnchor),
|
|
|
+ stackView.leadingAnchor.constraint(greaterThanOrEqualTo: container.leadingAnchor, constant: 40),
|
|
|
+ stackView.trailingAnchor.constraint(lessThanOrEqualTo: container.trailingAnchor, constant: -40)
|
|
|
+ ])
|
|
|
+
|
|
|
+ container.isHidden = true
|
|
|
+ return container
|
|
|
+ }()
|
|
|
|
|
|
private let addButton: UIButton = {
|
|
|
let b = UIButton(type: .custom)
|
|
|
@@ -151,7 +196,7 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
scrollView.addSubview(contentView)
|
|
|
|
|
|
// Header
|
|
|
- [titleLabel, settingsButton, petCard, tagScroll, recordStack].forEach {
|
|
|
+ [titleLabel, settingsButton, petCard, tagScroll, recordStack, emptyStateView].forEach {
|
|
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
|
|
contentView.addSubview($0)
|
|
|
}
|
|
|
@@ -265,6 +310,12 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
recordStack.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12),
|
|
|
recordStack.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -12),
|
|
|
recordStack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -24),
|
|
|
+
|
|
|
+ // Empty state view
|
|
|
+ emptyStateView.topAnchor.constraint(equalTo: tagScroll.bottomAnchor, constant: 50),
|
|
|
+ emptyStateView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12),
|
|
|
+ emptyStateView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -12),
|
|
|
+ emptyStateView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -100),
|
|
|
|
|
|
// Bottom tab bar
|
|
|
tabBarView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
|
@@ -417,9 +468,29 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
}
|
|
|
|
|
|
@objc private func tapAddPet() {
|
|
|
+
|
|
|
+ // 检查登录状态
|
|
|
+ let isLoggedIn = UserDefaults.standard.bool(forKey: "isLogggedIn")
|
|
|
+ let userToken = UserDefaults.standard.string(forKey: "userToken")
|
|
|
+
|
|
|
+ // 如果没有登录状态或者没有有效的token,弹出登录界面
|
|
|
+ if !isLoggedIn || userToken?.isEmpty != false {
|
|
|
+ showLoginViewController()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
let vc = AddPetViewController()
|
|
|
navigationController?.pushViewController(vc, animated: true)
|
|
|
}
|
|
|
+
|
|
|
+ private func showLoginViewController() {
|
|
|
+ let loginVC = LoginViewController()
|
|
|
+ let navController = UINavigationController(rootViewController: loginVC)
|
|
|
+ navController.modalPresentationStyle = .fullScreen
|
|
|
+ present(navController, animated: true)
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
private func styleAddPetButton() {
|
|
|
@@ -436,6 +507,7 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
// addPetButton.isHidden = value
|
|
|
tagScroll.isHidden = !value
|
|
|
recordStack.isHidden = !value
|
|
|
+ emptyStateView.isHidden = value // 没有宠物时显示空视图
|
|
|
emptyTipLabel.isHidden = value
|
|
|
emptyBanner.isHidden = value
|
|
|
if !value {
|
|
|
@@ -536,12 +608,35 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
}
|
|
|
|
|
|
@objc private func tapQuickEvent() {
|
|
|
+ print("快速进入 随手小记")
|
|
|
+
|
|
|
+ // 检查登录状态
|
|
|
+ let isLoggedIn = UserDefaults.standard.bool(forKey: "isLogggedIn")
|
|
|
+ let userToken = UserDefaults.standard.string(forKey: "userToken")
|
|
|
+
|
|
|
+ // 如果没有登录状态或者没有有效的token,弹出登录界面
|
|
|
+ if !isLoggedIn || userToken?.isEmpty != false {
|
|
|
+ showLoginViewController()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
hideActionMenu()
|
|
|
showCreateRecordSheet()
|
|
|
}
|
|
|
|
|
|
@objc private func tapQuickNote() {
|
|
|
print("快速进入 记账")
|
|
|
+
|
|
|
+ // 检查登录状态
|
|
|
+ let isLoggedIn = UserDefaults.standard.bool(forKey: "isLogggedIn")
|
|
|
+ let userToken = UserDefaults.standard.string(forKey: "userToken")
|
|
|
+
|
|
|
+ // 如果没有登录状态或者没有有效的token,弹出登录界面
|
|
|
+ if !isLoggedIn || userToken?.isEmpty != false {
|
|
|
+ showLoginViewController()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
hideActionMenu()
|
|
|
showBookkeepingQuickSheet()
|
|
|
}
|
|
|
@@ -915,24 +1010,26 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
UserDefaults.standard.set(false, forKey: "isLogggedIn")
|
|
|
UserDefaults.standard.removeObject(forKey: "userToken")
|
|
|
|
|
|
- // 创建登录界面
|
|
|
+// // 创建登录界面
|
|
|
let loginVC = LoginViewController()
|
|
|
let navController = UINavigationController(rootViewController: loginVC)
|
|
|
-
|
|
|
- // 获取当前窗口
|
|
|
- guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 设置根视图控制器为登录界面
|
|
|
- window.rootViewController = navController
|
|
|
-
|
|
|
- // 添加切换动画
|
|
|
- UIView.transition(with: window,
|
|
|
- duration: 0.4,
|
|
|
- options: .transitionCrossDissolve,
|
|
|
- animations: nil,
|
|
|
- completion: nil)
|
|
|
+ navController.modalPresentationStyle = .fullScreen
|
|
|
+ self.present(navController, animated: true)
|
|
|
+//
|
|
|
+// // 获取当前窗口
|
|
|
+// guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else {
|
|
|
+// return
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 设置根视图控制器为登录界面
|
|
|
+// window.rootViewController = navController
|
|
|
+//
|
|
|
+// // 添加切换动画
|
|
|
+// UIView.transition(with: window,
|
|
|
+// duration: 0.4,
|
|
|
+// options: .transitionCrossDissolve,
|
|
|
+// animations: nil,
|
|
|
+// completion: nil)
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1159,8 +1256,15 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
recordStack.removeArrangedSubview(v)
|
|
|
v.removeFromSuperview()
|
|
|
}
|
|
|
- guard !list.isEmpty else { return }
|
|
|
-
|
|
|
+
|
|
|
+ // 检查是否有数据,决定显示列表还是空视图
|
|
|
+ if list.isEmpty {
|
|
|
+ showEmptyState()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ hideEmptyState()
|
|
|
+
|
|
|
let placeholder = UIImage(named: "peihead") ?? UIImage(systemName: "pawprint.circle")!
|
|
|
|
|
|
for rec in list {
|
|
|
@@ -1192,6 +1296,17 @@ class HomeViewController: UIViewController, UIPopoverPresentationControllerDeleg
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // MARK: - 空视图管理
|
|
|
+ private func showEmptyState() {
|
|
|
+ emptyStateView.isHidden = false
|
|
|
+ recordStack.isHidden = true
|
|
|
+ }
|
|
|
+
|
|
|
+ private func hideEmptyState() {
|
|
|
+ emptyStateView.isHidden = true
|
|
|
+ recordStack.isHidden = false
|
|
|
+ }
|
|
|
+
|
|
|
private func formatAPIDate(_ s: String?) -> String {
|
|
|
guard let s = s, !s.isEmpty else { return "" }
|
|
|
let inFmt = DateFormatter()
|