从弹出框/弹出框中定义的数据填充自定义 tableView 单元格中的字段
Posted
技术标签:
【中文标题】从弹出框/弹出框中定义的数据填充自定义 tableView 单元格中的字段【英文标题】:Populating fields in a custom tableView cell from data defined in a popover/popup 【发布时间】:2021-08-23 00:08:33 【问题描述】:在我的应用程序的设置 VC 中,我有一个带有 5 个不同自定义单元格的表格视图。我需要一些帮助的单元格设置了默认的开始和结束时间。这是使用带有日期/时间控件的弹出框/弹出窗口来完成的,该控件使用 segue 打开。此单元格包含 2 个按钮(开始和结束)和 2 个字段(开始和结束)。当点击其中一个按钮时,会显示相应的弹出框/弹出框。然后用户定义所需时间并点击完成按钮。我正在使用协议/委托方法从弹出框/弹出框传递时间字符串。这目前有效,但有一个例外。我希望新定义的时间填充单元格中相应的开始或结束字段。我的想法是将所有这些代码移动到自定义 tableViewCell 中,在那里我可以完全访问这些字段,但我似乎无法做到这一点。无法识别将 prepare(for segue: 移动到单元格文件。有没有办法从自定义单元格执行此 segue?或者有人对使用我当前的设置填充字段有想法吗?提前感谢您的帮助。
// All of this code is in the tableView controller except the last part where noted
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "quote_Presets_StartTime" // # 2
let storyboard : UIStoryboard = UIStoryboard(name: K.StoryboardID.date_Picker_SB, bundle: nil)
var popupVC : Date_Popup_VC = storyboard.instantiateViewController(withIdentifier: K.StoryboardID.date_Popup_VC) as! Date_Popup_VC
let navigationController = UINavigationController(rootViewController: popupVC)
let deviceName = UIDevice().type
let deviceString: String = ("\(deviceName)")
if deviceString.contains(K.theDevice.iPad)
popupVC = segue.destination as! Date_Popup_VC
if ModelData.isInline() // Wheel
popupVC.preferredContentSize = CGSize(width: 320, height: 300)
else // Inline
popupVC.preferredContentSize = CGSize(width: 350, height: 150)
navigationController.isNavigationBarHidden = true
else if deviceString.contains(K.theDevice.iPhone)
present(navigationController, animated: true, completion: nil)
navigationController.isNavigationBarHidden = false
popupVC.theBtn = 2
let formattedTime = ModelData.formattedTime_Read(time_Db: new_Start_Time)
popupVC.theDate = formattedTime
popupVC.timeStart_Delegate = self
else if segue.identifier == "quote_Presets_EndTime" // # 3
let storyboard : UIStoryboard = UIStoryboard(name: K.StoryboardID.date_Picker_SB, bundle: nil)
var popupVC : Date_Popup_VC = storyboard.instantiateViewController(withIdentifier: K.StoryboardID.date_Popup_VC) as! Date_Popup_VC
let navigationController = UINavigationController(rootViewController: popupVC)
let deviceName = UIDevice().type
let deviceString: String = ("\(deviceName)")
if deviceString.contains(K.theDevice.iPad)
popupVC = segue.destination as! Date_Popup_VC
if ModelData.isInline() // Wheel
popupVC.preferredContentSize = CGSize(width: 320, height: 300)
else // Inline
popupVC.preferredContentSize = CGSize(width: 350, height: 150)
navigationController.isNavigationBarHidden = true
else if deviceString.contains(K.theDevice.iPhone)
present(navigationController, animated: true, completion: nil)
navigationController.isNavigationBarHidden = false
popupVC.theBtn = 3
let formattedTime = ModelData.formattedTime_Read(time_Db: new_End_Time)
popupVC.theDate = formattedTime
popupVC.timeEnd_Delegate = self
// Executed from the cellForRowAt code
@objc
func setTheTimes(sender: UIButton)
switch sender.tag
case 0:
performSegue(withIdentifier: "quote_Presets_StartTime", sender: Any?.self)
case 1:
performSegue(withIdentifier: "quote_Presets_EndTime", sender: Any?.self)
default: break
extension Quote_Presets_VC: UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 10
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
// cell_05 Time
let cell_05 = tableView.dequeueReusableCell(withIdentifier: K.ReuseIdentifier.defaultTime_Cell, for: indexPath) as! DefaultTime_Cell
cell_05.backgroundColor = Theme.current.darkAccentColor
cell_05.selectionStyle = .none
cell_05.delegate = self as SaveData_Time
cell_05.label_Outlet.labelTextColorOnly_Attributes(txt: K.Titles.defaultStartEnd, txtWgt: .regular)
cell_05.labelStart_Outlet.labelTextColorOnly_Attributes(txt: K.Titles.start, txtWgt: .regular)
cell_05.labelEnd_Outlet.labelTextColorOnly_Attributes(txt: K.Titles.end, txtWgt: .regular)
cell_05.startBtn_Outlet.addTarget(self, action: #selector(setTheTimes), for: .touchUpInside)
cell_05.endButton_Outlet.addTarget(self, action: #selector(setTheTimes), for: .touchUpInside)
cell_05.fldStart_Outlet.textField_Simple(text: ModelData.timeConversionTo_12(time24: new_Start_Time))
cell_05.fldEnd_Outlet.textField_Simple(text: ModelData.timeConversionTo_12(time24: new_End_Time))
switch indexPath.row
case 9: // Time
cell_05.fldStart_Outlet.tag = 0
cell_05.fldEnd_Outlet.tag = 1
cell_05.startBtn_Outlet.tag = 0
cell_05.endButton_Outlet.tag = 1
return cell_05
default: break
return UITableViewCell()
// These are the delegates for the protocol to pass the time string
extension Quote_Presets_VC: TimeStart_DatePopupDelegate, TimeEnd_DatePopupDelegate
func saveTimeStart(value: String)
var originalValue: String = ""
for theValue in presetsArray
originalValue = theValue.start_Time
let formattedValue = ModelData.timeConversionTo_24(time12: value)
if formattedValue != originalValue
new_Start_Time = value
save_Array_Quote[6] = K.AppFacing_Titles.true_
else
save_Array_Quote[6] = K.AppFacing_Titles.false_
setSaveBtn_QuotePresets()
func clearTimeStart(value: String)
// startFld_Outlet.text = value
func saveTimeEnd(value: String)
var originalValue: String = ""
for theValue in presetsArray
originalValue = theValue.end_Time
let formattedValue = ModelData.timeConversionTo_24(time12: value)
if formattedValue != originalValue
new_End_Time = value
save_Array_Quote[7] = K.AppFacing_Titles.true_
else
save_Array_Quote[7] = K.AppFacing_Titles.false_
setSaveBtn_QuotePresets()
func clearTimeEnd(value: String)
// endFld_Outlet.text = value
// The code below is the current tableview cell code
protocol SaveData_Time: AnyObject
func setSaveBtn_QuotePresets()
class DefaultTime_Cell: UITableViewCell
@IBOutlet weak var label_Outlet: UILabel!
@IBOutlet weak var labelStart_Outlet: UILabel!
@IBOutlet weak var fldStart_Outlet: UITextField!
@IBOutlet weak var fldEnd_Outlet: UITextField!
@IBOutlet weak var labelEnd_Outlet: UILabel!
@IBOutlet weak var startFldHgt_Constraint: NSLayoutConstraint!
@IBOutlet weak var startBtn_Outlet: UIButton!
@IBOutlet weak var endButton_Outlet: UIButton!
weak var delegate: SaveData_Time?
override func awakeFromNib()
super.awakeFromNib()
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
@IBAction func startBtn_Tapped(_ sender: UIButton)
// This throws an error that cannot find performSegue in scope
//performSegue(withIdentifier: "quote_Presets_StartTime", sender: Any?.self)
@IBAction func endBtn_Tapped(_ sender: UIButton)
// This throws an error that cannot find performSegue in scope
//performSegue(withIdentifier: "quote_Presets_EndTime", sender: Any?.self)
【问题讨论】:
【参考方案1】:首先,在需要之前不要将日期转换为字符串。改为传递 Date
值。
而且,要回答有关将更多逻辑移入单元格的问题,请不要这样做。保持你的观点简单。
我只需在 DateCell 中添加两个闭包,以指示是否点击了按钮:
class DateCell: UITableViewCell
@IBOutlet weak var startDateButton: UIButton!
@IBOutlet weak var endDateButton: UIButton!
var didTapStart: () -> Void =
var didTapEnd: () -> Void =
@IBAction func didSelectStart(_ sender: UIButton)
didTapStart()
@IBAction func didSelectEnd(_ sender: UIButton)
didTapEnd()
在您的日期编辑器中,您可以使用委托或闭包来指示日期已更改。我将在这里使用闭包:
class DateEditor: UIViewController
var dateDidChange: (Date) -> Void = _ in
// ...
我不是 segues 的粉丝,但如果你真的想使用一个,那么创建两个 segues,一个用于编辑开始日期,一个用于编辑结束日期:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
guard let cell = sender as? UITableViewCell,
let row = tableView.indexPath(for: cell)?.row,
let vc = segue.destination as? DateEditor else return
if segue.identifier == "editStartDate"
vc.date = dates[row].start
else
vc.date = dates[row].end
vc.dateDidChange = [weak self] date in
if segue.identifier == "editStartDate"
self?.dates[row].start = date
else
self?.dates[row].end = date
self?.tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .fade)
只要点击其中一个按钮,就触发 segue:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "DateCell", for: indexPath) as! DateCell
cell.startDateButton.setTitle(
DateFormatter.awesome.string(from: self.dates[indexPath.row].start),
for: .normal
)
cell.endDateButton.setTitle(
DateFormatter.awesome.string(from: self.dates[indexPath.row].end),
for: .normal
)
cell.didTapStart = [weak self] in
self?.performSegue(withIdentifier: "editStartDate", sender: cell)
cell.didTapEnd = [weak self] in
self?.performSegue(withIdentifier: "editEndDate", sender: cell)
return cell
这是我用来格式化日期的:
extension DateFormatter
static let awesome: DateFormatter =
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
()
【讨论】:
感谢@Rob 非常彻底的回答。非常感激。我需要一点时间来消化这些信息。以上是关于从弹出框/弹出框中定义的数据填充自定义 tableView 单元格中的字段的主要内容,如果未能解决你的问题,请参考以下文章