协议/委托 - 找不到委托
Protocol / Delegate - Delegate found nil
几天来我一直在绞尽脑汁想弄明白这个问题。我有两个视图控制器(WorkoutViewController 和 WorkoutAlertViewController)。 WorkoutViewController 是创建的所有锻炼的 tableView。它具有用于编辑/删除的滑动操作。这个视图控制器还有一个“+”作为打开 WorkoutAlertViewController 的条形按钮。此外,在滑动操作编辑中,WorkoutAlertViewController 打开。
WorkoutAlertViewController 从用户那里获取输入,并在按下添加按钮时将数据传回 WorkoutViewController。
问题来了。我有一个协议/委托,用于将用户的输入输入到 WorkoutAlertViewController 并将信息传递回 WorkoutViewController 以填充 tableView。这很好用!但是,当用户想要编辑锻炼时,我需要该锻炼的信息来填充 WorkoutAlertViewController 上的条目。无论我尝试过什么,该协议的代表总是 returns nil。因此,没有传递任何数据。
这里是 WorkoutViewController 的必要代码:
protocol PassExistingWorkout {
func didTapEdit(workout: Workout)
}
class WorkoutViewController: UIViewController {
var workoutDelegate: PassExistingWorkout!
@IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
let alertVC = storyboard!.instantiateViewController(withIdentifier: "WorkoutVC") as! WorkoutAlertViewController
alertVC.alertDelegate = self
present(alertVC, animated: true, completion: nil)
}
}
extension WorkoutViewController: PassNewWorkout {
func didTapAdd(name: String, time: String, date: Date) {
workoutName = name
averageTime = time
creationDate = date
let newWorkout = Workout()
newWorkout.name = workoutName
newWorkout.dateCreated = creationDate
newWorkout.time = averageTime
saveWorkout(workout: newWorkout)
}
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { (action, view, actionPerformed) in
if let _ = tableView.cellForRow(at: indexPath){
do {
try self.realm.write {
self.realm.delete(self.workoutItems![indexPath.row])
}
} catch {
print("Error saving category \(error)")
}
}
tableView.reloadData()
}
deleteAction.backgroundColor = .red
let editAction = UIContextualAction(style: .normal, title: "Edit") { (action, view, actionPerformed) in
let alertVC = self.storyboard!.instantiateViewController(identifier: "WorkoutVC") as! WorkoutAlertViewController
self.present(alertVC, animated: true, completion: nil)
if let _ = tableView.cellForRow(at: indexPath){
self.passedWorkout = self.workoutItems![indexPath.row]
self.workoutDelegate.didTapEdit(workout: self.passedWorkout)
}
}
editAction.backgroundColor = .gray
return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
}
}
这是 WorkoutAlertViewController 的代码:
protocol PassNewWorkout {
func didTapAdd(name: String, time: String, date: Date)
}
class WorkoutAlertViewController: UIViewController {
var alertDelegate: PassNewWorkout!
@IBAction func addButtonPressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
workoutName = workoutTextField.text!
creationDate = datePicker.date
averageTime = timeTextField.text!
alertDelegate.didTapAdd(name: workoutName, time: averageTime, date: creationDate)
}
override func viewDidLoad() {
super.viewDidLoad()
let workoutVC = storyboard!.instantiateViewController(identifier: "Main") as! WorkoutViewController
workoutVC.workoutDelegate = self
}
extension WorkoutAlertViewController: PassExistingWorkout {
func didTapEdit(workout: Workout) {
receivedWorkout = workout
}
}
应用程序在调用时在 editAction 中崩溃:
self.workoutDelegate.didTapEdit(workout: self.passedWorkout)
错误:致命错误:在隐式解包可选值时意外发现 nil:文件。据我所知,没有创建 workoutDelegate (nil)。
一如既往,非常感谢任何指导。
您不需要委托进行转发通信..您可以直接调用该函数
let editAction = UIContextualAction(style: .normal, title: "Edit") { (action, view, actionPerformed) in
let alertVC = self.storyboard!.instantiateViewController(identifier: "WorkoutVC") as! WorkoutAlertViewController
self.passedWorkout = self.workoutItems![indexPath.row]
alertVC.didTapEdit(workout: self.passedWorkout)
self.present(alertVC, animated: true, completion: nil)
}
在你其他class做
class WorkoutAlertViewController: UIViewController {
var alertDelegate: PassNewWorkout!
@IBAction func addButtonPressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
workoutName = workoutTextField.text!
creationDate = datePicker.date
averageTime = timeTextField.text!
alertDelegate.didTapAdd(name: workoutName, time: averageTime, date: creationDate)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func didTapEdit(workout: Workout) {
receivedWorkout = workout
}
}
几天来我一直在绞尽脑汁想弄明白这个问题。我有两个视图控制器(WorkoutViewController 和 WorkoutAlertViewController)。 WorkoutViewController 是创建的所有锻炼的 tableView。它具有用于编辑/删除的滑动操作。这个视图控制器还有一个“+”作为打开 WorkoutAlertViewController 的条形按钮。此外,在滑动操作编辑中,WorkoutAlertViewController 打开。
WorkoutAlertViewController 从用户那里获取输入,并在按下添加按钮时将数据传回 WorkoutViewController。
问题来了。我有一个协议/委托,用于将用户的输入输入到 WorkoutAlertViewController 并将信息传递回 WorkoutViewController 以填充 tableView。这很好用!但是,当用户想要编辑锻炼时,我需要该锻炼的信息来填充 WorkoutAlertViewController 上的条目。无论我尝试过什么,该协议的代表总是 returns nil。因此,没有传递任何数据。
这里是 WorkoutViewController 的必要代码:
protocol PassExistingWorkout {
func didTapEdit(workout: Workout)
}
class WorkoutViewController: UIViewController {
var workoutDelegate: PassExistingWorkout!
@IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
let alertVC = storyboard!.instantiateViewController(withIdentifier: "WorkoutVC") as! WorkoutAlertViewController
alertVC.alertDelegate = self
present(alertVC, animated: true, completion: nil)
}
}
extension WorkoutViewController: PassNewWorkout {
func didTapAdd(name: String, time: String, date: Date) {
workoutName = name
averageTime = time
creationDate = date
let newWorkout = Workout()
newWorkout.name = workoutName
newWorkout.dateCreated = creationDate
newWorkout.time = averageTime
saveWorkout(workout: newWorkout)
}
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { (action, view, actionPerformed) in
if let _ = tableView.cellForRow(at: indexPath){
do {
try self.realm.write {
self.realm.delete(self.workoutItems![indexPath.row])
}
} catch {
print("Error saving category \(error)")
}
}
tableView.reloadData()
}
deleteAction.backgroundColor = .red
let editAction = UIContextualAction(style: .normal, title: "Edit") { (action, view, actionPerformed) in
let alertVC = self.storyboard!.instantiateViewController(identifier: "WorkoutVC") as! WorkoutAlertViewController
self.present(alertVC, animated: true, completion: nil)
if let _ = tableView.cellForRow(at: indexPath){
self.passedWorkout = self.workoutItems![indexPath.row]
self.workoutDelegate.didTapEdit(workout: self.passedWorkout)
}
}
editAction.backgroundColor = .gray
return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
}
}
这是 WorkoutAlertViewController 的代码:
protocol PassNewWorkout {
func didTapAdd(name: String, time: String, date: Date)
}
class WorkoutAlertViewController: UIViewController {
var alertDelegate: PassNewWorkout!
@IBAction func addButtonPressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
workoutName = workoutTextField.text!
creationDate = datePicker.date
averageTime = timeTextField.text!
alertDelegate.didTapAdd(name: workoutName, time: averageTime, date: creationDate)
}
override func viewDidLoad() {
super.viewDidLoad()
let workoutVC = storyboard!.instantiateViewController(identifier: "Main") as! WorkoutViewController
workoutVC.workoutDelegate = self
}
extension WorkoutAlertViewController: PassExistingWorkout {
func didTapEdit(workout: Workout) {
receivedWorkout = workout
}
}
应用程序在调用时在 editAction 中崩溃:
self.workoutDelegate.didTapEdit(workout: self.passedWorkout)
错误:致命错误:在隐式解包可选值时意外发现 nil:文件。据我所知,没有创建 workoutDelegate (nil)。
一如既往,非常感谢任何指导。
您不需要委托进行转发通信..您可以直接调用该函数
let editAction = UIContextualAction(style: .normal, title: "Edit") { (action, view, actionPerformed) in
let alertVC = self.storyboard!.instantiateViewController(identifier: "WorkoutVC") as! WorkoutAlertViewController
self.passedWorkout = self.workoutItems![indexPath.row]
alertVC.didTapEdit(workout: self.passedWorkout)
self.present(alertVC, animated: true, completion: nil)
}
在你其他class做
class WorkoutAlertViewController: UIViewController {
var alertDelegate: PassNewWorkout!
@IBAction func addButtonPressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
workoutName = workoutTextField.text!
creationDate = datePicker.date
averageTime = timeTextField.text!
alertDelegate.didTapAdd(name: workoutName, time: averageTime, date: creationDate)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func didTapEdit(workout: Workout) {
receivedWorkout = workout
}
}