如何实现点击按钮启停、每5秒添加带时间戳的UITableView行
Got it, to make your table view automatically add a row with a timestamp every 5 seconds, we’ll use a Timer to handle the repeating action. Here’s how to implement it:
First, add the necessary properties to your view controller: a timer to manage the repeats, and an array to store your timestamp entries. Then, start the timer when the view loads, and make sure to stop it when the view is dismissed to avoid memory issues. Finally, create a helper method that generates the timestamp, adds it to your data array, and inserts the new row into the table.
Here’s the full code:
import UIKit class ViewController: UIViewController, UITableViewDataSource { @IBOutlet weak var tableView: UITableView! // Stores all our timestamp entries private var dataArray: [String] = [] // Timer for the auto-add functionality private var autoAddTimer: Timer? override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self // Start the timer – it'll fire every 5 seconds autoAddTimer = Timer.scheduledTimer( timeInterval: 5.0, target: self, selector: #selector(addTimestampRow), userInfo: nil, repeats: true ) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Stop the timer when the view is no longer visible autoAddTimer?.invalidate() autoAddTimer = nil } @objc private func addTimestampRow() { // Format the current date/time into a readable string let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" let timestamp = dateFormatter.string(from: Date()) // Add the timestamp to our array and insert the new row dataArray.append(timestamp) let newIndexPath = IndexPath(row: dataArray.count - 1, section: 0) // Update the table view (safe to wrap in main thread, though timers run on main by default) DispatchQueue.main.async { self.tableView.insertRows(at: [newIndexPath], with: .automatic) } } // MARK: UITableView Data Source Methods func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel?.text = dataArray[indexPath.row] return cell } }
Just remember to set up a table view cell with the identifier "Cell" in Interface Builder, and connect your tableView outlet properly!
For this, we’ll reuse the timer approach, but tie it to your existing start/stop buttons. We’ll start the timer when the "Start" button is tapped, and stop it when "Stop" is pressed. Here’s how to modify your code:
We’ll add the timer property, update your button actions to manage the timer, and use the same helper method to add timestamp rows.
Here’s the updated code:
import UIKit class ViewController: UIViewController, UITableViewDataSource { @IBOutlet weak var tableView: UITableView! private var dataArray: [String] = [] private var autoAddTimer: Timer? override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Clean up the timer when the view is dismissed autoAddTimer?.invalidate() autoAddTimer = nil } @IBAction func addCellTapped(_ sender: Any) { // Only start the timer if it's not already running guard autoAddTimer == nil else { return } autoAddTimer = Timer.scheduledTimer( timeInterval: 5.0, target: self, selector: #selector(addTimestampRow), userInfo: nil, repeats: true ) } @IBAction func stopCellTapped(_ sender: Any) { // Stop the timer and reset it autoAddTimer?.invalidate() autoAddTimer = nil } @objc private func addTimestampRow() { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" let timestamp = dateFormatter.string(from: Date()) dataArray.append(timestamp) let newIndexPath = IndexPath(row: dataArray.count - 1, section: 0) DispatchQueue.main.async { self.tableView.insertRows(at: [newIndexPath], with: .automatic) } } // MARK: UITableView Data Source Methods func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel?.text = dataArray[indexPath.row] return cell } }
Key notes here:
- We check if the timer is already running before starting it in
addCellTappedto avoid creating multiple timers. - In
stopCellTapped, we invalidate the timer and set it to nil to ensure it’s fully stopped. - Always clean up the timer in
viewWillDisappearto prevent it from running in the background after the view is gone.
内容的提问来源于stack exchange,提问作者Chandan Anand

