Files
note/Note/ViewController.swift
T

218 lines
7.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// ViewController.swift
// Note
//
// Created by fish on 2026/7/12.
//
import UIKit
class ViewController: UIViewController {
private var tableView: UITableView!
private var editButton: UIBarButtonItem!
private let menuOrderKey = "homeMenuOrder"
private struct MenuItem {
let icon: String
let iconColor: UIColor
let title: String
let identifier: String
}
private let defaultMenuItems: [MenuItem] = [
MenuItem(icon: "tray.full", iconColor: .systemIndigo, title: "收集箱", identifier: "inbox"),
MenuItem(icon: "note.text", iconColor: .systemYellow, title: "打开备忘录", identifier: "notes"),
MenuItem(icon: "doc.text", iconColor: .systemBlue, title: "格式化日志", identifier: "formatLog"),
MenuItem(icon: "text.alignleft", iconColor: .systemGreen, title: "格式化笔记", identifier: "formatNote"),
MenuItem(icon: "folder", iconColor: .systemOrange, title: "打开文件", identifier: "files")
]
private var menuItems: [[MenuItem]] = []
override func viewDidLoad() {
super.viewDidLoad()
menuItems = [loadMenuOrder()]
setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
updateInboxBadge()
}
private func setupUI() {
title = "首页"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
view.backgroundColor = .systemGroupedBackground
editButton = UIBarButtonItem(title: "编辑", style: .plain, target: self, action: #selector(didTapEditButton))
navigationItem.rightBarButtonItem = editButton
tableView = UITableView(frame: .zero, style: .insetGrouped)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "menuCell")
tableView.backgroundColor = .systemGroupedBackground
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
@objc private func didTapEditButton() {
tableView.setEditing(!tableView.isEditing, animated: true)
editButton.title = tableView.isEditing ? "完成" : "编辑"
}
private func loadMenuOrder() -> [MenuItem] {
guard let savedOrder = UserDefaults.standard.array(forKey: menuOrderKey) as? [String] else {
return defaultMenuItems
}
var orderedItems: [MenuItem] = []
for identifier in savedOrder {
if let item = defaultMenuItems.first(where: { $0.identifier == identifier }) {
orderedItems.append(item)
}
}
let remaining = defaultMenuItems.filter { item in
!orderedItems.contains { $0.identifier == item.identifier }
}
return orderedItems + remaining
}
private func saveMenuOrder() {
let identifiers = menuItems.flatMap { $0.map(\.identifier) }
UserDefaults.standard.set(identifiers, forKey: menuOrderKey)
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return menuItems.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menuItems[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath)
let item = menuItems[indexPath.section][indexPath.row]
var config = cell.defaultContentConfiguration()
config.text = item.title
config.image = UIImage(systemName: item.icon)
config.imageProperties.tintColor = item.iconColor
config.imageToTextPadding = 12
cell.contentConfiguration = config
cell.accessoryType = tableView.isEditing ? .none : .disclosureIndicator
cell.selectionStyle = tableView.isEditing ? .none : .default
return cell
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
guard sourceIndexPath != destinationIndexPath else { return }
let item = menuItems[sourceIndexPath.section].remove(at: sourceIndexPath.row)
menuItems[destinationIndexPath.section].insert(item, at: destinationIndexPath.row)
saveMenuOrder()
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard !tableView.isEditing else { return }
let item = menuItems[indexPath.section][indexPath.row]
switch item.identifier {
case "inbox":
let viewController = ClipInboxViewController()
navigationController?.pushViewController(viewController, animated: true)
case "notes":
openSystemNotesApp()
case "formatLog":
let viewController = FormatLogViewController()
navigationController?.pushViewController(viewController, animated: true)
case "formatNote":
let viewController = FormatNoteViewController()
navigationController?.pushViewController(viewController, animated: true)
case "files":
openFilesApp()
default:
break
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
private func updateInboxBadge() {
Task {
guard let count = try? await ClipStore.shared.count(), count > 0 else {
await MainActor.run {
self.updateInboxTitle("收集箱")
}
return
}
await MainActor.run {
self.updateInboxTitle("收集箱(\(count)")
}
}
}
private func updateInboxTitle(_ title: String) {
for (sectionIndex, section) in menuItems.enumerated() {
for (rowIndex, item) in section.enumerated() {
if item.identifier == "inbox" {
menuItems[sectionIndex][rowIndex] = MenuItem(
icon: item.icon,
iconColor: item.iconColor,
title: title,
identifier: item.identifier
)
let indexPath = IndexPath(row: rowIndex, section: sectionIndex)
tableView.reloadRows(at: [indexPath], with: .none)
return
}
}
}
}
private func openSystemNotesApp() {
openURLIfPossible("mobilenotes://")
}
private func openFilesApp() {
openURLIfPossible("shareddocuments://")
}
private func openURLIfPossible(_ string: String) {
guard let url = URL(string: string) else { return }
guard UIApplication.shared.canOpenURL(url) else { return }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}