iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0
生成式 AI

三十天解鎖上下文超能力:MCP 實戰系列 第 24

Day 24 - 跨平台實戰 IV:組裝聊天主畫面,讓 iOS app 對話動起來

  • 分享至 

  • xImage
  •  

大家好,鐵人賽堂堂邁入第二十四日!

昨天,我們精心設計了聊天畫面的最小單位——MainTableViewCell。今天,我們的任務是將這些獨立的氣泡組裝起來,搭建出一個大家所熟悉的、可以上下滾動的聊天主介面。我們將使用 iOS 開發中最核心的元件之一:UITableView

一、主畫面介面佈局 (MainViewController.xib)

首先,我們來設計主畫面的外觀。在 Xcode 中打開 MainViewController.xib,並從元件庫中拖拉以下三個核心元件到畫面上:

  1. UITableView (聊天列表): 佔據畫面的大部分空間,用來顯示我們的聊天氣泡。
  2. UITextField (訊息輸入框): 放置在畫面底部,讓使用者可以輸入文字。
  3. UIButton (發送按鈕): 放置在輸入框旁邊。

完成後,使用 @IBOutlet 將這三個元件連接到 MainViewController.swift 檔案中。

// MainViewController.swift
import UIKit

class MainViewController: UIViewController {
    
    @IBOutlet weak var tbvChat: UITableView!
    @IBOutlet weak var btnSend: UIButton!
    @IBOutlet weak var txfMessage: UITextField!
    
    // 用一個陣列來儲存所有的對話訊息
    var messages: [Message] = []
    
    // ...
}

二、賦予 UITableView 生命

光有介面是不夠的,我們需要用程式碼告訴 UITableView 該如何顯示資料。這個過程主要透過兩個重要的代理 (Protocol) 來完成:UITableViewDataSourceUITableViewDelegate

MainViewController.swiftviewDidLoad 方法中,我們進行初步設定:

// MainViewController.swift
func setupTbv() {
    // 1. 註冊我們昨天設計的 Cell XIB
    tbvChat.register(UINib(nibName: "MainTableViewCell", bundle: nil), forCellReuseIdentifier: MainTableViewCell.identifile)
    
    // 2. 設定代理
    tbvChat.dataSource = self
    tbvChat.delegate = self
    
    // 3. UI 優化
    tbvChat.separatorStyle = .none // 隱藏 Cell 之間的分隔線
}

接著,我們讓 MainViewController 遵循這兩個代理,並實現最核心的兩個方法:

// MainViewController.swift

// 讓 ViewController 遵循 UITableViewDataSource 和 UITableViewDelegate
extension MainViewController: UITableViewDelegate, UITableViewDataSource {
    
    // 方法一:告訴 TableView 有多少行
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return messages.count // 行數等於我們訊息陣列的數量
    }
    
    // 方法二:告訴 TableView 每一行該長什麼樣子
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 1. 從重用池中取出我們自訂的 Cell
        let cell = tableView.dequeueReusableCell(withIdentifier: MainTableViewCell.identifile, for: indexPath) as! MainTableViewCell
        
        // 2. 取得對應的訊息資料
        let message = messages[indexPath.row]
        
        // 3. 呼叫我們昨天寫的 configure 方法,讓 Cell 自己更新外觀
        cell.configure(with: message)
        
        return cell
    }
}

三、顯示第一段靜態對話

為了在連接 API 之前先驗證我們的 UI 是否正常,我們先在 MainViewController 中加入一個 loadInitialMessages 函式,用來載入一些「假資料」。

// MainViewController.swift
func loadInitialMessages() {
    // 建立幾筆測試訊息
    messages = [
        Message(text: "你好!我可以幫你查詢伺服器資安事件。", sender: .bot),
        Message(text: "查詢最近的資安事件", sender: .user),
        Message(text: "好的,以下是最近的資安事件:...", sender: .bot)
    ]
    
    // 重新載入 TableView 讓畫面更新
    tbvChat.reloadData()
}

最後,在 viewDidLoad 中呼叫 loadInitialMessages()。現在,運行你的 App,你將會看到一個漂亮的、包含三則對話的聊天畫面並且傳送一個訊息出去,把回覆設定成hi,如下圖:

截圖 2025-09-25 15.07.31

可以看到我們的訊息成功送出囉!!

今日總結

今天,我們成功地將獨立的聊天氣泡,組裝成一個完整的聊天主畫面。我們學會了:

  1. 如何設定 UITableView,並將其與資料來源連接。
  2. 實現 UITableViewDataSource 的核心方法,動態地產生 Cell。
  3. 如何載入靜態資料,來驗證 UI 佈局的正確性。

我們的 App 現在已經「有形有樣」了。明天,我們將進入最激動人心的環節——我們會將 UI 與 NetworkManager 連接起來,發送第一筆真實的 API 請求,並將後端 Agent 的回覆,動態地顯示在畫面上!


上一篇
Day 23 - 跨平台實戰 III:UI 的最小單位,設計聊天氣泡 TableViewCell
系列文
三十天解鎖上下文超能力:MCP 實戰24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言