在我的应用程序的设置VC上,我有一个表视图与5个不同的自定义单元格。单元格我需要一些帮助设置默认的开始和结束时间。这是使用带有日期/时间控件的弹窗/弹出窗口完成的,该控件使用segue打开。此单元格包含2个按钮(开始和结束)和2个字段(开始和结束)。当其中一个按钮被点击时,相应的弹出窗口/弹出显示。然后用户定义所需的时间并点击完成按钮。我使用一个协议/委托方法来传递时间字符串从popover/popup。目前这是可行的,只有一个例外。我希望新定义的时间填充单元格中相应的开始或结束字段。我的想法是将所有这些代码移动到自定义tableViewCell中,我可以完全访问字段,但我似乎无法使其工作。无法识别将prepareforsegue:移动到单元格文件。有没有办法从自定义单元格中执行这个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)
}
}
首先,除非需要,否则不要将日期转换为字符串。传递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 }
// ...
}
我不是segue的粉丝,但如果你真的想使用一个,那么创建两个segue,一个用于编辑开始日期,一个用于编辑结束日期:
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
}()
}