如何在使用自定义 TableViewCell 按钮执行 segue 之前更新数据?
How to update data before using a custom TableViewCell button to perform a segue?
目前,我有一个屏幕显示带有自定义单元格的 TableView,每个单元格都包含一个 timeButton。当您按下 timeButton 时,它会转至 pop-up 屏幕一次 select。当它被关闭时,它会更新主屏幕上时间按钮的标题。
我有一个委托方法,每次按下它时,都会用按下的 timeButton 的 indexPath.row 更新 rowIndex(实例变量)。我注意到 segue 方法在 rowIndex 由 pressedTimeButton(cell: TaskCell) 委托方法更新之前运行。如何让委托方法在 segue 发生之前更新 rowIndex?
这里是VC的主要代码:
struct Task {
var name, time: String
}
class MainViewController: UIViewController {
@IBOutlet weak var taskList: UITableView!
var tasks = [Task]()
var rowIndex = Int()
override func viewDidLoad() {
super.viewDidLoad()
// Set initial task time's value
tasks.append(Task(name: "", time: "Set time"))
taskList.delegate = self
taskList.dataSource = self
}
// Segue to pop-up screen
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueToPopUp" {
let controller = segue.destination as! PopUpViewController
// ISSUE: rowIndex isn't updated when segue starts
if tasks[rowIndex].time != "Set time" {
// if time is already set, reset time to "0:00"
tasks[rowIndex].time = "0:00"
} else {
// if time is not set
}
}
// Unwind from pop-up screen
@IBAction func unwindFromPopUp(_ segue: UIStoryboardSegue) {
// code to update "timeButton" with selected time
tasks[rowIndex].time = controller.selectedTaskTime
...
}
}
extension TaskListViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
// Return custom cell + data to show in table view
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) as! TaskCell
cell.delegate = self
// Configure timeButton in taskCell
let task = tasks[indexPath.row]
cell.timeButton.setTitle(task.time, for: .normal)
return cell
}
}
extension TaskListViewController: TaskCellDelegate {
// ISSUE: rowIndex updates after segue method instead of before
func pressedTimeButton(onCell cell: TaskCell) {
if let indexPath = taskList.indexPath(for: cell) {
rowIndex = indexPath.row
}
}
}
这是我的自定义单元的代码 + 它的委托协议:
protocol TaskCellDelegate: class {
func pressedTimeButton(onCell cell: TaskCell)
}
class TaskCell: UITableViewCell, UITextFieldDelegate {
weak var delegate: TaskCellDelegate?
@IBOutlet weak var timeButton: UIButton!
override func prepareForReuse() {
super.prepareForReuse()
delegate = nil
}
@IBAction func tapTimeButton(_ sender: UIButton) {
delegate?.pressedTimeButton(onCell: self)
}
}
好像你已经在故事板中设置了从 tableView cell/timeButton 到 PopUpViewController
的 segue,它的作用是一旦 cell/timeButton 被点击就会触发 segue,而不是拖动一个 segue从 ViewController
到 PopUpViewController
这样只有当你调用 self.performSegue(withIdentifier: "segueToPopUp", sender: nil)
时才会执行 segue
同时实现func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
(如果您希望在点击单元格时执行 segue)点击单元格时将触发此方法,执行您的任务时间更新。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
rowIndex = indexPath.row
self.performSegue(withIdentifier: "segueToPopUp", sender: nil)
}
如果您不想在点击单元格时继续转场,而是只需要在时间按钮上转场,请点击您现有的 pressedTimeButton
方法现在应该可以正常工作了
extension TaskListViewController: TaskCellDelegate {
func pressedTimeButton(onCell cell: TaskCell) {
if let indexPath = taskList.indexPath(for: cell) {
rowIndex = indexPath.row
self.performSegue(withIdentifier: "segueToPopUp", sender: nil)
}
}
}
目前,我有一个屏幕显示带有自定义单元格的 TableView,每个单元格都包含一个 timeButton。当您按下 timeButton 时,它会转至 pop-up 屏幕一次 select。当它被关闭时,它会更新主屏幕上时间按钮的标题。
我有一个委托方法,每次按下它时,都会用按下的 timeButton 的 indexPath.row 更新 rowIndex(实例变量)。我注意到 segue 方法在 rowIndex 由 pressedTimeButton(cell: TaskCell) 委托方法更新之前运行。如何让委托方法在 segue 发生之前更新 rowIndex?
这里是VC的主要代码:
struct Task {
var name, time: String
}
class MainViewController: UIViewController {
@IBOutlet weak var taskList: UITableView!
var tasks = [Task]()
var rowIndex = Int()
override func viewDidLoad() {
super.viewDidLoad()
// Set initial task time's value
tasks.append(Task(name: "", time: "Set time"))
taskList.delegate = self
taskList.dataSource = self
}
// Segue to pop-up screen
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueToPopUp" {
let controller = segue.destination as! PopUpViewController
// ISSUE: rowIndex isn't updated when segue starts
if tasks[rowIndex].time != "Set time" {
// if time is already set, reset time to "0:00"
tasks[rowIndex].time = "0:00"
} else {
// if time is not set
}
}
// Unwind from pop-up screen
@IBAction func unwindFromPopUp(_ segue: UIStoryboardSegue) {
// code to update "timeButton" with selected time
tasks[rowIndex].time = controller.selectedTaskTime
...
}
}
extension TaskListViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
// Return custom cell + data to show in table view
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) as! TaskCell
cell.delegate = self
// Configure timeButton in taskCell
let task = tasks[indexPath.row]
cell.timeButton.setTitle(task.time, for: .normal)
return cell
}
}
extension TaskListViewController: TaskCellDelegate {
// ISSUE: rowIndex updates after segue method instead of before
func pressedTimeButton(onCell cell: TaskCell) {
if let indexPath = taskList.indexPath(for: cell) {
rowIndex = indexPath.row
}
}
}
这是我的自定义单元的代码 + 它的委托协议:
protocol TaskCellDelegate: class {
func pressedTimeButton(onCell cell: TaskCell)
}
class TaskCell: UITableViewCell, UITextFieldDelegate {
weak var delegate: TaskCellDelegate?
@IBOutlet weak var timeButton: UIButton!
override func prepareForReuse() {
super.prepareForReuse()
delegate = nil
}
@IBAction func tapTimeButton(_ sender: UIButton) {
delegate?.pressedTimeButton(onCell: self)
}
}
好像你已经在故事板中设置了从 tableView cell/timeButton 到 PopUpViewController
的 segue,它的作用是一旦 cell/timeButton 被点击就会触发 segue,而不是拖动一个 segue从 ViewController
到 PopUpViewController
这样只有当你调用 self.performSegue(withIdentifier: "segueToPopUp", sender: nil)
同时实现func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
(如果您希望在点击单元格时执行 segue)点击单元格时将触发此方法,执行您的任务时间更新。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
rowIndex = indexPath.row
self.performSegue(withIdentifier: "segueToPopUp", sender: nil)
}
如果您不想在点击单元格时继续转场,而是只需要在时间按钮上转场,请点击您现有的 pressedTimeButton
方法现在应该可以正常工作了
extension TaskListViewController: TaskCellDelegate {
func pressedTimeButton(onCell cell: TaskCell) {
if let indexPath = taskList.indexPath(for: cell) {
rowIndex = indexPath.row
self.performSegue(withIdentifier: "segueToPopUp", sender: nil)
}
}
}