ios 情节串连图板,Segues,如果我想从一个元素中使用两个Segues,我应该怎么做?

lawou6xi  于 2023-02-06  发布在  iOS
关注(0)|答案(1)|浏览(122)

这是我的第一个问题。我有TableViewController,我想从一个原始数据中使用两个segue。一个segue应该在点击行时工作,第二个是这一行的动作,每一个都需要显示不同的视图控制器,我不明白我怎么能做到,因为我不能从一行创建两个segues。问题是这两种情况都需要调用prepare函数,它只使用segue调用,而当我使用performSegue时,它没有被调用。

override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let editAction = UIContextualAction(style: .normal, title: "Add"){(_,_, completionHandler) in
            self.performSegue(withIdentifier: "editQuiz", sender: self)
            tableView.reloadData()
        }
        let deleteAction = UIContextualAction(style: .destructive, title: "Delete"){(_,_, completionHandler) in
            CoreDataManager.shared.deleteSomeQuizData(data: CoreDataManager.shared.quizzes[indexPath.row], indexNumber: indexPath.row)
            self.navigationItem.title = "\(CoreDataManager.shared.quizzes.count) quizzes"
            tableView.reloadData()
        }
        return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard let indexPath = tableView.indexPathForSelectedRow else {return}
        print(segue.source)
        if segue.identifier == "editQuiz" {
            guard let destination = segue.destination as? AddWordsViewController else{return}
        }
        if segue.identifier == "showQuiz" {
            guard let destination = segue.destination as? QuizViewController else{return}
            destination.from = Int(CoreDataManager.shared.quizzes[indexPath.row].from)
            destination.to = Int(CoreDataManager.shared.quizzes[indexPath.row].to)
        }
    }

prepare(for segue:)仅在从行segue调用到另一个ViewController并且没有使用performSegue调用时才起作用。此外,如果我创建了从TableViewController到ViewController的两个segue并且没有调用performSegue,则转换不起作用。
所有segues标识符设置正确。
即使我努力

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.performSegue(withIdentifier: "showQuiz", sender: self)
    }

prepare(for segue:)正在呼叫,但在

let editAction = UIContextualAction(style: .normal, title: "Add"){(_,_, completionHandler) in
            self.performSegue(withIdentifier: "editQuiz", sender: self)
            tableView.reloadData()
        }

它没有呼叫。

6uxekuva

6uxekuva1#

看起来你几乎所有的设置都正确,除了...
prepare for segue代码中,首先要检查所选的行:

guard let indexPath = tableView.indexPathForSelectedRow else {return}

如果从“Edit”操作调用performSegue,则表格视图将不会有选定的行。
对我来说测试起来有点坚韧,因为我没有所有的数据管理和目标控制器,但这应该可以解决这个问题(如果你在故事板中正确设置了segues):

override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let editAction = UIContextualAction(style: .normal, title: "Add"){(_,_, completionHandler) in
        
        // instead of passing self as sender
        //self.performSegue(withIdentifier: "editQuiz", sender: self)
        
        // pass the indexPath
        self.performSegue(withIdentifier: "editQuiz", sender: indexPath)
        
        // no need to reload data here
        //tableView.reloadData()
    }
    let deleteAction = UIContextualAction(style: .destructive, title: "Delete"){(_,_, completionHandler) in
        CoreDataManager.shared.deleteSomeQuizData(data: CoreDataManager.shared.quizzes[indexPath.row], indexNumber: indexPath.row)
        self.navigationItem.title = "Title \(indexPath.row)" // "\(CoreDataManager.shared.quizzes.count) quizzes"
        tableView.reloadData()
    }
    return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "editQuiz" {
        // do something before segue to AddWordsViewController
        if let indexPath = sender as? IndexPath {
            print("editQuiz with IndexPath: \(indexPath)")
        }
    }
    if segue.identifier == "showQuiz" {
        guard let indexPath = tableView.indexPathForSelectedRow,
              let destination = segue.destination as? QuizViewController
        else {
            // note: this will NOT Stop the segue
            return
        }
        destination.from = Int(CoreDataManager.shared.quizzes[indexPath.row].from)
        destination.to = Int(CoreDataManager.shared.quizzes[indexPath.row].to)
    }
    
}

正如我在评论中提到的:* “为了给予自己最大的控制权,不要在那种情况下使用segues ..."*
为此,从情节提要中删除这些片段
相反,可以根据需要使用类似下面的代码来示例化“目标”视图控制器:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
    // instantiate QuizViewController
    if let vc = self.storyboard?.instantiateViewController(withIdentifier: "QuizViewController") as? QuizViewController {

        vc.from = Int(CoreDataManager.shared.quizzes[indexPath.row].from)
        vc.to = Int(CoreDataManager.shared.quizzes[indexPath.row].to)
        
        self.navigationController?.pushViewController(vc, animated: true)

    }
}
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let editAction = UIContextualAction(style: .normal, title: "Add"){(_,_, completionHandler) in
        
        // instantiate AddWordsViewController
        if let vc = self.storyboard?.instantiateViewController(withIdentifier: "AddWordsViewController") as? AddWordsViewController {

            // do something before showing AddWordsViewController
            self.navigationController?.pushViewController(vc, animated: true)

        }
        
    }
    let deleteAction = UIContextualAction(style: .destructive, title: "Delete"){(_,_, completionHandler) in
        CoreDataManager.shared.deleteSomeQuizData(data: CoreDataManager.shared.quizzes[indexPath.row], indexNumber: indexPath.row)
        self.navigationItem.title = "Title \(indexPath.row)" // "\(CoreDataManager.shared.quizzes.count) quizzes"
        tableView.reloadData()
    }
    return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
}

相关问题