从RouteTableViewController
退回到AlarmAddEditViewController
时发生崩溃。在控制台中,我看到以下消息:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<fix_it_mapView.RouteTableViewController: 0x7ffad352e4a0>) has no segue with identifier 'routeUnwindSegue''.
它实际上在这里被声明为另一个tableVC:
import Foundation
struct Id {
static let stopIdentifier = "Alarm-ios-swift-stop"
static let snoozeIdentifier = "Alarm-ios-swift-snooze"
static let addSegueIdentifier = "addSegue"
static let editSegueIdentifier = "editSegue"
static let saveSegueIdentifier = "saveEditSegue"
static let soundSegueIdentifier = "soundSegue"
static let labelSegueIdentifier = "labelEditSegue"
static let weekdaysSegueIdentifier = "weekdaysSegue"
static let settingIdentifier = "setting"
static let musicIdentifier = "musicIdentifier"
static let alarmCellIdentifier = "alarmCell"
static let routeSegueIdentifier = "routeSegue"
static let routeIdentifier = "routeIdentifier"
static let labelUnwindIdentifier = "labelUnwindSegue"
static let soundUnwindIdentifier = "soundUnwindSegue"
static let weekdaysUnwindIdentifier = "weekdaysUnwindSegue"
static let routeUnwindIdentifier = "routeUnwindSegue"
}
这是RouteTableViewController
:
import UIKit
class RouteTableViewController: UITableViewController {
var numberOfRoutes = NewMapViewController.userRoutesNameArray.count
var routeLabel: String!
var routeId: String!
var dataPassed: String?
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
}
// override func viewWillDisappear(_ animated: Bool) {
// performSegue(withIdentifier: Id.routeUnwindIdentifier, sender: self)
// }
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
guard let header = view as? UITableViewHeaderFooterView else { return }
header.textLabel?.textColor = UIColor.gray
header.textLabel?.font = UIFont.boldSystemFont(ofSize: 10)
header.textLabel?.frame = header.frame
header.textLabel?.textAlignment = .left
}
// MARK: - Table view data source
//DECIDE HOW MANY SECTIONS
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
//DECIDE HOW MANY ROWS ARE IN EACH SECTION
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return NewMapViewController.userRoutesNameArray.count
}
//SET THE TITLE FOR EACH SECTION BASED ON ARRAY ELEMENTS
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "ROTTE DISPONIBILI"
}
//SET HEIGHT FOR HEADER IN SECTION
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: Id.routeIdentifier)
if(cell == nil) {
cell = UITableViewCell(
style: UITableViewCellStyle.default, reuseIdentifier: Id.routeIdentifier)
}
cell!.textLabel!.text = NewMapViewController.userRoutesNameArray[indexPath.item]
if cell!.textLabel!.text == routeLabel {
cell!.accessoryType = UITableViewCellAccessoryType.checkmark
}
return cell!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
// cell?.accessoryType = UITableViewCellAccessoryType.checkmark
routeLabel = cell?.textLabel?.text!
cell?.setSelected(true, animated: true)
cell?.setSelected(false, animated: true)
let cells = tableView.visibleCells
for c in cells {
let section = tableView.indexPath(for: c)?.section
if (section == indexPath.section && c != cell) {
c.accessoryType = UITableViewCellAccessoryType.none
}
}
routeLabel = cell!.textLabel!.text
performSegue(withIdentifier: Id.routeUnwindIdentifier, sender: self) // crash
//
// self.dismiss(animated: true, completion: nil) // doesnt gee selected to receiver vc
}
}
这是ÀlarmAddEditViewController`:
import UIKit
import Foundation
import MediaPlayer
class AlarmAddEditViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var tableView: UITableView!
var alarmScheduler: AlarmSchedulerDelegate = Scheduler()
var alarmModel: Alarms = Alarms()
var segueInfo: SegueInfo!
var snoozeEnabled: Bool = false
var enabled: Bool!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
alarmModel=Alarms()
tableView.reloadData()
snoozeEnabled = segueInfo.snoozeEnabled
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func saveEditAlarm(_ sender: AnyObject) {
let date = Scheduler.correctSecondComponent(date: datePicker.date)
let index = segueInfo.curCellIndex
var tempAlarm = Alarm()
tempAlarm.date = date
tempAlarm.label = segueInfo.label
tempAlarm.enabled = true
tempAlarm.routeLabel = segueInfo.routeLabel
tempAlarm.mediaLabel = segueInfo.mediaLabel
tempAlarm.mediaID = segueInfo.mediaID
tempAlarm.snoozeEnabled = snoozeEnabled
tempAlarm.repeatWeekdays = segueInfo.repeatWeekdays
tempAlarm.uuid = UUID().uuidString
tempAlarm.onSnooze = false
if segueInfo.isEditMode {
alarmModel.alarms[index] = tempAlarm
}
else {
alarmModel.alarms.append(tempAlarm)
}
self.performSegue(withIdentifier: Id.saveSegueIdentifier, sender: self)
}
func numberOfSections(in tableView: UITableView) -> Int {
// Return the number of sections.
if segueInfo.isEditMode {
return 2
}
else {
return 1
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 5
}
else {
return 1
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: Id.settingIdentifier)
if(cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: Id.settingIdentifier)
}
if indexPath.section == 0 {
if indexPath.row == 0 {
cell!.textLabel!.text = "Repeat"
cell!.detailTextLabel!.text = WeekdaysViewController.repeatText(weekdays: segueInfo.repeatWeekdays)
cell!.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
}
else if indexPath.row == 1 {
cell!.textLabel!.text = "Label"
cell!.detailTextLabel!.text = segueInfo.label
cell!.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
}
else if indexPath.row == 2 {
cell!.textLabel!.text = "Sound"
cell!.detailTextLabel!.text = segueInfo.mediaLabel
cell!.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
}
else if indexPath.row == 3 {
cell!.textLabel!.text = "Route"
cell!.detailTextLabel!.text = segueInfo.routeLabel
cell!.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
}
// else if indexPath.row == 3 {
else if indexPath.row == 4 {
cell!.textLabel!.text = "Snooze"
let sw = UISwitch(frame: CGRect())
sw.addTarget(self, action: #selector(AlarmAddEditViewController.snoozeSwitchTapped(_:)), for: UIControlEvents.touchUpInside)
if snoozeEnabled {
sw.setOn(true, animated: false)
}
cell!.accessoryView = sw
}
}
else if indexPath.section == 1 {
cell = UITableViewCell(
style: UITableViewCellStyle.default, reuseIdentifier: Id.settingIdentifier)
cell!.textLabel!.text = "Delete Alarm"
cell!.textLabel!.textAlignment = .center
cell!.textLabel!.textColor = UIColor.red
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
if indexPath.section == 0 {
switch indexPath.row{
case 0:
performSegue(withIdentifier: Id.weekdaysSegueIdentifier, sender: self)
cell?.setSelected(true, animated: false)
cell?.setSelected(false, animated: false)
case 1:
performSegue(withIdentifier: Id.labelSegueIdentifier, sender: self)
cell?.setSelected(true, animated: false)
cell?.setSelected(false, animated: false)
case 2:
performSegue(withIdentifier: Id.soundSegueIdentifier, sender: self)
cell?.setSelected(true, animated: false)
cell?.setSelected(false, animated: false)
case 3:
performSegue(withIdentifier: Id.routeSegueIdentifier, sender: self)
cell?.setSelected(true, animated: false)
cell?.setSelected(false, animated: false)
default:
break
}
}
else if indexPath.section == 1 {
//delete alarm
alarmModel.alarms.remove(at: segueInfo.curCellIndex)
performSegue(withIdentifier: Id.saveSegueIdentifier, sender: self)
}
}
@IBAction func snoozeSwitchTapped (_ sender: UISwitch) {
snoozeEnabled = sender.isOn
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == Id.saveSegueIdentifier {
let dist = segue.destination as! MainAlarmViewController
let cells = dist.tableView.visibleCells
for cell in cells {
let sw = cell.accessoryView as! UISwitch
if sw.tag > segueInfo.curCellIndex
{
sw.tag -= 1
}
}
alarmScheduler.reSchedule()
}
else if segue.identifier == Id.soundSegueIdentifier {
//TODO
let dist = segue.destination as! MediaViewController
dist.mediaID = segueInfo.mediaID
dist.mediaLabel = segueInfo.mediaLabel
}
else if segue.identifier == Id.labelSegueIdentifier {
let dist = segue.destination as! LabelEditViewController
dist.label = segueInfo.label
}
else if segue.identifier == Id.weekdaysSegueIdentifier {
let dist = segue.destination as! WeekdaysViewController
dist.weekdays = segueInfo.repeatWeekdays
}
else if segue.identifier == Id.routeSegueIdentifier {
let dist = segue.destination as! RouteTableViewController
dist.routeLabel = segueInfo.routeLabel
}
}
@IBAction func unwindFromLabelEditView(_ segue: UIStoryboardSegue) {
let src = segue.source as! LabelEditViewController
segueInfo.label = src.label
}
@IBAction func unwindFromWeekdaysView(_ segue: UIStoryboardSegue) {
let src = segue.source as! WeekdaysViewController
segueInfo.repeatWeekdays = src.weekdays
}
@IBAction func unwindFromMediaView(_ segue: UIStoryboardSegue) {
let src = segue.source as! MediaViewController
segueInfo.mediaLabel = src.mediaLabel
segueInfo.mediaID = src.mediaID
}
@IBAction func unwindFromRouteView(_ segue: UIStoryboardSegue) {
let src = segue.source as! RouteTableViewController
segueInfo.routeLabel = src.routeLabel
// segueInfo.routeId = src.routeId
}
}
和有效的VC展开示例:
class LabelEditViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var labelTextField: UITextField!
var label: String!
override func viewDidLoad() {
super.viewDidLoad()
labelTextField.becomeFirstResponder()
// Do any additional setup after loading the view.
self.labelTextField.delegate = self
labelTextField.text = label
//defined in UITextInputTraits protocol
labelTextField.returnKeyType = UIReturnKeyType.done
labelTextField.enablesReturnKeyAutomatically = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
label = textField.text!
performSegue(withIdentifier: Id.labelUnwindIdentifier, sender: self)
//This method can be used when no state passing is needed
//navigationController?.popViewController(animated: true)
return false
}
}
我确实像往常一样连接了展开,并且在检查器中看起来好像已将其连接为其他tableVC或labelVC。
您能看到RouteTableVIewController
有什么问题吗?
答案 0 :(得分:1)
您尚未将标识符分配给展开搜索。
要解决此问题:
Unwind segue to "unwindFromRouteView:"
。 (要打开文档大纲视图,请在ViewController下面的情节提要中单击View as: iPhone 8 (wC hR)
左侧的图标)。通过单击选择展开序列。routeUnwindSegue
。Unwind segue "routeUnwindSegue" to "unwindFromRouteView:"
。