iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
Mobile Development

Xcode x Swift Vibe coding進階開發之旅系列 第 14

Xcode x Swift Vibe coding進階開發之旅 第十四天 點名系統(7) 記錄頁面與刪除功能

  • 分享至 

  • xImage
  •  

說明

已經快做完了,看來用AI寫程式速度超快 /images/emoticon/emoticon08.gif

指令

btn可以切換tbv顯示人員資料與簽到紀錄 tbv左滑可以刪除該項紀錄 在listview裡

心得

指令如果沒有加最後一行的話會變成修改Mainview.

回答

https://ithelp.ithome.com.tw/upload/images/20250926/20168187Wi4iKyTmYi.png

程式

// 存儲所有使用者的陣列
    private var users: Results<user>?
    
    // 存儲所有簽到記錄的陣列
    private var checkInRecords: Results<CheckInRecord>?
    
    // 定義顯示模式
    enum DisplayMode {
        case users
        case checkInRecords
    }
    
    // 當前顯示模式
    private var currentDisplayMode: DisplayMode = .users
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // 設置導航欄
        setupNavigationBar()
        
        // 設置切換顯示模式按鈕
        setupSwitchModeButton()
        
        // 設置 TableView
        setupTableView()
        
        // 載入使用者數據
        loadUsers()
    }
    
    // 設置導航欄
    private func setupNavigationBar() {
        title = "人員列表"
        
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = UIColor(red: 173/255, green: 216/255, blue: 230/255, alpha: 1.0) // 淡藍色
        appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
        
        navigationController?.navigationBar.standardAppearance = appearance
        navigationController?.navigationBar.scrollEdgeAppearance = appearance
        navigationController?.navigationBar.compactAppearance = appearance
        
        // 確保導航欄不透明
        navigationController?.navigationBar.isTranslucent = false
    }
    
    // 設置切換顯示模式按鈕
    private func setupSwitchModeButton() {
        let switchButton = UIBarButtonItem(
            title: "切換到簽到記錄",
            style: .plain,
            target: self,
            action: #selector(switchModeButtonTapped)
        )
        navigationItem.rightBarButtonItem = switchButton
    }
    
    // 切換顯示模式按鈕點擊事件
    @objc private func switchModeButtonTapped() {
        // 切換顯示模式
        currentDisplayMode = (currentDisplayMode == .users) ? .checkInRecords : .users
        
        // 更新按鈕標題
        if let switchButton = navigationItem.rightBarButtonItem {
            switchButton.title = (currentDisplayMode == .users) ? "切換到簽到記錄" : "切換到人員列表"
        }
        
        // 根據當前模式載入對應數據
        if currentDisplayMode == .users {
            loadUsers()
        } else {
            loadCheckInRecords()
        }
        
        // 更新導航欄標題
        title = (currentDisplayMode == .users) ? "人員列表" : "簽到記錄"
    }
    
    // 設置 TableView
    private func setupTableView() {
        tbvlist.delegate = self
        tbvlist.dataSource = self
        
        // 註冊 cell
        tbvlist.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        
        // 設置行高
        tbvlist.rowHeight = 60
    }
    
    // 載入使用者數據
    private func loadUsers() {
        let realm = try! Realm()
        users = realm.objects(user.self).sorted(byKeyPath: "createdAt", ascending: false)
        tbvlist.reloadData()
    }
    
    // 載入簽到記錄
    private func loadCheckInRecords() {
        let realm = try! Realm()
        checkInRecords = realm.objects(CheckInRecord.self).sorted(byKeyPath: "checkInTime", ascending: false)
        tbvlist.reloadData()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // 根據當前模式載入對應數據
        if currentDisplayMode == .users {
            loadUsers()
        } else {
            loadCheckInRecords()
        }
    }
    
    // 格式化日期
    private func formatDate(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter.string(from: date)
    }
}

// MARK: - UITableViewDataSource, UITableViewDelegate
extension listViewController: UITableViewDataSource, UITableViewDelegate {
    
    // 返回表格有幾個區域
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    // 返回每個區域有多少行
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch currentDisplayMode {
        case .users:
            return users?.count ?? 0
        case .checkInRecords:
            return checkInRecords?.count ?? 0
        }
    }
    
    // 返回每一行的內容
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        
        switch currentDisplayMode {
        case .users:
            // 獲取對應的使用者資料
            if let currentUser = users?[indexPath.row] {
                cell.textLabel?.text = "\(currentUser.Name) (\(currentUser.userId))"
            } else {
                cell.textLabel?.text = "未知使用者"
            }
        case .checkInRecords:
            // 獲取對應的簽到記錄
            if let record = checkInRecords?[indexPath.row] {
                // 嘗試獲取用戶名
                let realm = try! Realm()
                let userObj = realm.objects(user.self).filter("userId == %@", record.userId).first
                let userName = userObj?.Name ?? "未知用戶"
                
                cell.textLabel?.text = "\(userName) - 簽到時間: \(formatDate(record.checkInTime))"
            } else {
                cell.textLabel?.text = "未知記錄"
            }
        }
        
        return cell
    }
    
    // 行被選中時的處理
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        switch currentDisplayMode {
        case .users:
            // 獲取選中的使用者
            guard let selectedUser = users?[indexPath.row] else { return }
            
            // 顯示用戶詳細資訊
            showUserDetails(user: selectedUser)
            
        case .checkInRecords:
            // 獲取選中的簽到記錄
            guard let selectedRecord = checkInRecords?[indexPath.row] else { return }
            
            // 顯示記錄詳細資訊
            showRecordDetails(record: selectedRecord)
        }
    }
    
    // 支援左滑刪除操作
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true // 允許所有行可編輯(左滑)
    }
    
    // 定義左滑操作
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            switch currentDisplayMode {
            case .users:
                // 刪除用戶
                deleteUser(at: indexPath)
            case .checkInRecords:
                // 刪除簽到記錄
                deleteCheckInRecord(at: indexPath)
            }
        }
    }
    
    // 顯示用戶詳細資訊
    private func showUserDetails(user: user) {
        let alertController = UIAlertController(
            title: "用戶詳細資訊",
            message: "ID: \(user.userId)\n姓名: \(user.Name)\n創建時間: \(formatDate(user.createdAt))",
            preferredStyle: .alert
        )
        
        // 添加確認按鈕
        let okAction = UIAlertAction(title: "確定", style: .default)
        alertController.addAction(okAction)
        
        present(alertController, animated: true)
    }
    
    // 顯示記錄詳細資訊
    private func showRecordDetails(record: CheckInRecord) {
        // 嘗試獲取用戶名
        let realm = try! Realm()
        let userObj = realm.objects(user.self).filter("userId == %@", record.userId).first
        let userName = userObj?.Name ?? "未知用戶"
        
        let alertController = UIAlertController(
            title: "簽到記錄詳細資訊",
            message: "用戶: \(userName)\n用戶ID: \(record.userId)\n簽到時間: \(formatDate(record.checkInTime))\n備註: \(record.note ?? "無")",
            preferredStyle: .alert
        )
        
        // 添加確認按鈕
        let okAction = UIAlertAction(title: "確定", style: .default)
        alertController.addAction(okAction)
        
        present(alertController, animated: true)
    }
    
    // 刪除用戶
    private func deleteUser(at indexPath: IndexPath) {
        guard let userToDelete = users?[indexPath.row] else {
            showErrorAlert(message: "找不到要刪除的用戶")
            return
        }
        
        // 顯示確認刪除的警告框
        let alertController = UIAlertController(
            title: "確認刪除",
            message: "確定要刪除用戶「\(userToDelete.Name)」嗎?此操作無法復原,且將刪除該用戶的所有簽到記錄。",
            preferredStyle: .alert
        )
        
        let cancelAction = UIAlertAction(title: "取消", style: .cancel)
        
        let deleteAction = UIAlertAction(title: "刪除", style: .destructive) { [weak self] _ in
            guard let self = self else { return }
            
            let realm = try! Realm()
            
            do {
                // 刪除該用戶的所有簽到記錄
                let userRecords = realm.objects(CheckInRecord.self).filter("userId == %@", userToDelete.userId)
                
                try realm.write {
                    // 刪除相關記錄
                    realm.delete(userRecords)
                    // 刪除用戶
                    realm.delete(userToDelete)
                }
                
                // 重新加載數據
                self.loadUsers()
                
                // 顯示成功訊息
                self.showSuccessAlert(message: "用戶已成功刪除")
            } catch {
                self.showErrorAlert(message: "刪除失敗:\(error.localizedDescription)")
            }
        }
        
        alertController.addAction(cancelAction)
        alertController.addAction(deleteAction)
        
        present(alertController, animated: true)
    }
    
    // 刪除簽到記錄
    private func deleteCheckInRecord(at indexPath: IndexPath) {
        guard let recordToDelete = checkInRecords?[indexPath.row] else {
            showErrorAlert(message: "找不到要刪除的記錄")
            return
        }
        
        // 嘗試獲取用戶名
        let realm = try! Realm()
        let userObj = realm.objects(user.self).filter("userId == %@", recordToDelete.userId).first
        let userName = userObj?.Name ?? "未知用戶"
        
        // 顯示確認刪除的警告框
        let alertController = UIAlertController(
            title: "確認刪除",
            message: "確定要刪除 \(userName) 於 \(formatDate(recordToDelete.checkInTime)) 的簽到記錄嗎?此操作無法復原。",
            preferredStyle: .alert
        )
        
        let cancelAction = UIAlertAction(title: "取消", style: .cancel)
        
        let deleteAction = UIAlertAction(title: "刪除", style: .destructive) { [weak self] _ in
            guard let self = self else { return }
            
            do {
                try realm.write {
                    realm.delete(recordToDelete)
                }
                
                // 重新加載數據
                self.loadCheckInRecords()
                
                // 顯示成功訊息
                self.showSuccessAlert(message: "記錄已成功刪除")
            } catch {
                self.showErrorAlert(message: "刪除失敗:\(error.localizedDescription)")
            }
        }
        
        alertController.addAction(cancelAction)
        alertController.addAction(deleteAction)
        
        present(alertController, animated: true)
    }
    
    // 顯示成功訊息
    private func showSuccessAlert(message: String) {
        let alertController = UIAlertController(title: "成功", message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "確定", style: .default)
        alertController.addAction(okAction)
        present(alertController, animated: true)
    }
    
    // 顯示錯誤訊息
    private func showErrorAlert(message: String) {
        let alertController = UIAlertController(title: "錯誤", message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "確定", style: .default)
        alertController.addAction(okAction)
        present(alertController, animated: true)
    }
}


上一篇
Xcode x Swift Vibe coding進階開發之旅 第十三天 點名系統(6) 設定tableview簽到功能 及 即時時間顯示
下一篇
Xcode x Swift Vibe coding進階開發之旅 第十五天 點名系統(8) 增加時間限定
系列文
Xcode x Swift Vibe coding進階開發之旅16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言