You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:实现UITableView按事件时间自动排序与冲突校验

完整实现方案:UITableView事件自动排序+时间冲突校验

一、修正SessionModel的Date类型定义

直接把时间字段设为Date类型,避免字符串转Date的额外麻烦:

import Foundation

struct SessionModel: Codable {
    var startTime: Date
    var endTime: Date
    var title: String
    var location: String
}

二、解决Date与UILabel的显示问题

UILabel只能显示字符串,用DateFormatter把Date转成可读字符串,建议全局初始化一个避免重复创建:

// 可以放在ViewController或者单独的工具文件里
let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm" // 可根据需求自定义格式
    formatter.locale = Locale.current
    return formatter
}()

然后在PrototypeCell里完成数据绑定:

import UIKit

class PrototypeCell: UITableViewCell {
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var locationLabel: UILabel!
    
    func configure(with session: SessionModel) {
        titleLabel.text = session.title
        locationLabel.text = session.location
        // 把Date转成字符串显示
        let startStr = dateFormatter.string(from: session.startTime)
        let endStr = dateFormatter.string(from: session.endTime)
        timeLabel.text = "\(startStr) - \(endStr)"
    }
}

三、事件自动排序逻辑

每次添加新事件后,对数据源数组按startTime升序排序,再刷新TableView。以下是ViewController里的核心代码:

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    var sessions: [SessionModel] = [] // 数据源数组

    @IBAction func addButtonTapped(_ sender: UIBarButtonItem) {
        let addVC = storyboard?.instantiateViewController(withIdentifier: "AddSessionViewController") as! AddSessionViewController
        // 用闭包接收新事件
        addVC.onSessionAdded = { [weak self] newSession in
            guard let self = self else { return }
            // 先校验冲突,无冲突再添加排序
            if !self.isTimeConflict(with: newSession) {
                self.sessions.append(newSession)
                // 按开始时间升序排序
                self.sessions.sort { $0.startTime < $1.startTime }
                self.tableView.reloadData()
            } else {
                // 弹出冲突提示
                let alert = UIAlertController(title: "时间冲突", message: "该时间段已有其他事件,请重新选择", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "确定", style: .default))
                self.present(alert, animated: true)
            }
        }
        present(addVC, animated: true)
    }
}

四、时间冲突校验逻辑

在ViewController里添加校验方法,判断新事件是否和已有事件时间重叠:

private func isTimeConflict(with newSession: SessionModel) -> Bool {
    let newStart = newSession.startTime
    let newEnd = newSession.endTime
    
    for session in sessions {
        let existingStart = session.startTime
        let existingEnd = session.endTime
        
        // 三种冲突情况:新事件开始在已有事件区间内、结束在区间内、完全覆盖已有事件
        if (newStart >= existingStart && newStart < existingEnd) ||
           (newEnd > existingStart && newEnd <= existingEnd) ||
           (newStart <= existingStart && newEnd >= existingEnd) {
            return true
        }
    }
    return false
}

五、AddSessionViewController表单处理

修正表单输入校验,直接用UIDatePicker获取Date类型的时间:

class AddSessionViewController: UIViewController {
    @IBOutlet weak var titleTextField: UITextField!
    @IBOutlet weak var locationTextField: UITextField!
    @IBOutlet weak var startTimePicker: UIDatePicker!
    @IBOutlet weak var endTimePicker: UIDatePicker!
    
    // 定义回调闭包,传递新事件
    var onSessionAdded: ((SessionModel) -> Void)?

    @IBAction func addButtonTapped(_ sender: UIButton) {
        // 校验必填项
        guard let title = titleTextField.text, !title.isEmpty,
              let location = locationTextField.text, !location.isEmpty else {
            let alert = UIAlertController(title: "提示", message: "请填写完整事件信息", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default))
            present(alert, animated: true)
            return
        }
        
        let startTime = startTimePicker.date
        let endTime = endTimePicker.date
        
        // 校验结束时间不能早于开始时间
        guard endTime > startTime else {
            let alert = UIAlertController(title: "时间错误", message: "结束时间必须晚于开始时间", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default))
            present(alert, animated: true)
            return
        }
        
        // 创建事件模型并回调
        let newSession = SessionModel(startTime: startTime, endTime: endTime, title: title, location: location)
        onSessionAdded?(newSession)
        dismiss(animated: true)
    }
}

六、ViewController的TableView数据源方法

确保Cell配置正确:

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sessions.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "PrototypeCell", for: indexPath) as! PrototypeCell
        cell.configure(with: sessions[indexPath.row])
        return cell
    }
}

内容的提问来源于stack exchange,提问作者CalebGates

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:32:37