swift - UITableViewCell 中的 UIDatePicker 未正确显示并崩溃
问题描述
当用户选择行时,我尝试将 UIDatePicker 添加到 UITableViewCell 。我以编程方式将其添加到单元格中,并在单元格选择中切换其可见性。它在设备和模拟器上都可以正常工作。但是当我在 Xcode 中断开设备或按下停止并在模拟器中重新启动应用程序时 - UIDatePicker 被裁剪(部分可见)并在点击它时崩溃应用程序。
我试图在 tableview 控制器中这样做
var groomingDatePicker: UIDatePicker = {
let picker = UIDatePicker()
picker.datePickerMode = .date
return picker
}()
在 cellForRow...
let cell = UITableViewCell()
cell.textLabel?.text = some text
cell.backgroundColor = UIColor.white
cell.selectionStyle = .none
cell.contentView.addSubview(groomingDatePicker)
groomingDatePicker.translatesAutoresizingMaskIntoConstraints = false
groomingDatePicker.rightAnchor.constraint(equalTo: cell.rightAnchor, constant: -75).isActive = true
groomingDatePicker.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
groomingDatePicker.widthAnchor.constraint(equalToConstant: 150).isActive = true
groomingDatePicker.heightAnchor.constraint(equalTo: cell.heightAnchor).isActive = true
if petDefaults.bool(forKey: somekey) == true
{
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
groomingDatePicker.isHidden = false
} else {
cell.accessoryType = UITableViewCell.AccessoryType.none
groomingDatePicker.isHidden = true
}
return cell
我也尝试制作自定义 TableViewCell,结果是一样的
解决方案
假设您需要的是一个提醒数组,您将需要一个简单的数据模型来保存数据,因为您的 tableView 不是数据存储,它只是数据的显示。单元格被重复使用,因此您不能期望在滚动时保留该值。每次显示单元格时,都必须将其视为全新的显示,这意味着您必须将日期保存在数组中。
假设您有一个像这样的简单提醒结构
struct ReminderDetails
{
var description : String = ""
var date : Date = Date()
}
你有一个像这样声明的类变量
var reminders : [ReminderDetails] = []
// create some dummy data
reminders.append(ReminderDetails(description: "first thing to do", date: Date()))
reminders.append(ReminderDetails(description: "second thing to do", date: Date()))
reminders.append(ReminderDetails(description: "another thing to do", date: Date()))
然后当你创建你的单元格时,确保每次都设置提醒日期
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = UITableViewCell()
cell.textLabel?.text = reminders[indexPath.row].description
cell.backgroundColor = UIColor.white
cell.selectionStyle = .none
let groomingDatePicker: UIDatePicker = UIDatePicker()
groomingDatePicker.datePickerMode = .date
groomingDatePicker.date = reminders[indexPath.row].date
groomingDatePicker.tag = indexPath.row
// update the stored value whenever the value is changed
groomingDatePicker.addTarget(self, action: #selector(ViewController.datePickerValueChanged), for: UIControl.Event.valueChanged)
cell.contentView.addSubview(groomingDatePicker)
groomingDatePicker.translatesAutoresizingMaskIntoConstraints = false
groomingDatePicker.rightAnchor.constraint(equalTo: cell.rightAnchor, constant: 0).isActive = true
groomingDatePicker.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
groomingDatePicker.widthAnchor.constraint(equalToConstant: 150).isActive = true
groomingDatePicker.heightAnchor.constraint(equalTo: cell.heightAnchor).isActive = true
if petDefaults.bool(forKey: somekey) == true
{
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
groomingDatePicker.isHidden = false
} else {
cell.accessoryType = UITableViewCell.AccessoryType.none
groomingDatePicker.isHidden = true
}
return cell
}
当日期更新时,您需要采取一些措施,这就是
groomingDatePicker.addTarget(self, action: #selector(ViewController.datePickerValueChanged), for: UIControl.Event.valueChanged)
行用于 - 当日期更改时,datePickerValueChanged
调用该函数,传入发送者,以便您可以访问sender.tag
哪个让您知道该行,因此哪个控件已更新。
// date changed event
@objc func datePickerValueChanged(sender:UIDatePicker)
{
// update the reminder date for the right entry, based on the sender tag
reminders[sender.tag].date = sender.date
}
这只是更新类数组——如果你将它存储在数据库中,你将不得不在那里更新它——无论是每次更改某些内容时,还是作为最后的一个块。
推荐阅读
- c++ - 为什么 fetch_sub 不是释放操作?
- tensorflow - 来自 tf.train.import_meta_graph 的 UnicodeDecodeError
- r - 在 R 中,为什么 all(numeric(0)) 给出 TRUE 而 any(numeric(0)) 给出 FALSE?
- npm - 如何让 Modernizr 与 Webpack 4 一起工作
- c# - 参数在非常简单的数组上超出范围
- python - Python pandas获取数据框中组的第一个和最后一个索引,如果第一个也是最后一个则重复
- python - 使用感叹号对凯撒密码函数进行加密
- asp-classic - 在 Server.CreateObject("Scripting.FileSystemObject") 中创建要在 GetFolder 中使用的虚拟目录 IIS7
- java - 将一个无符号的 32 位整数转换为长度为 4 字节的字节数组,在 java 中反之亦然
- asp.net-core - 在 Web 环境中使用会话令牌管理 CosmosDb 会话一致性级别