Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 通过导航返回按钮传递数据_Ios_Swift_Uinavigationcontroller_Pass Data - Fatal编程技术网

Ios 通过导航返回按钮传递数据

Ios 通过导航返回按钮传递数据,ios,swift,uinavigationcontroller,pass-data,Ios,Swift,Uinavigationcontroller,Pass Data,我的处境是: 我正在使用prepare for segue将进度表中的4个数组传递给详细练习,效果很好!当我尝试将数据从详细练习控制器传回进度表控制器时,问题就开始了。我想使用默认的导航返回按钮返回到父视图。实际上,我正在使用这段代码,但它不起作用,数据从子视图传递到父视图,但我在进度表中看不到结果,似乎我需要刷新,但我还尝试在viewDidLoad之后重新加载数据,但它不起作用。有什么建议吗?多谢各位 override func viewWillDisappear(animated : Bo

我的处境是:

我正在使用prepare for segue将进度表中的4个数组传递给详细练习,效果很好!当我尝试将数据从详细练习控制器传回进度表控制器时,问题就开始了。我想使用默认的导航返回按钮返回到父视图。实际上,我正在使用这段代码,但它不起作用,数据从子视图传递到父视图,但我在进度表中看不到结果,似乎我需要刷新,但我还尝试在viewDidLoad之后重新加载数据,但它不起作用。有什么建议吗?多谢各位

override func viewWillDisappear(animated : Bool) {
    super.viewWillDisappear(animated)

    if (self.isMovingFromParentViewController()){
        print("n'drio")

        let historyView = self.storyboard!.instantiateViewControllerWithIdentifier("historyView") as! HistoryTableViewController
        historyView.isFirstTime = false
        historyView.arrayData = arrayDataDetails
        historyView.arrayRipetizioni = arrayRipetizioniDetails
        historyView.arrayPeso = arrayPesoDetails
        historyView.arrayRecupero = arrayRecuperoDetails
        historyView.tableView.reloadData()
    }
}

通常,协议和委托用于在屏幕之间来回传递数据

// Define a delegate that is known to both view controllers
protocol DetailsExerciseDelegate {
    func detailsWillDisappear(...);
}

class DetailsExerciseViewController {
    // Accept the delegate as a property on the details view controller
    var delegate : DetailsExerciseDelegate

    override func viewWillDisappear(animated : Bool) {
        super.viewWillDisappear(animated)

        // When you want to send data back to the caller
        // call the method on the delegate
        if let delegate = self.delegate {
            delegate.detailsWillDisappear(/* your data in one or more parameters */)
        }
    }
}

// Implement the delegate by adding the required function
class ProgressTableViewController: DetailsExerciseDelegate {
    ...

    func detailsWillDisappear(...) {
        // When the child calls the function, update the screen
        historyView.isFirstTime = false
        historyView.arrayData = arrayDataDetails
        historyView.arrayRipetizioni = arrayRipetizioniDetails
        historyView.arrayPeso = arrayPesoDetails
        historyView.arrayRecupero = arrayRecuperoDetails
        historyView.tableView.reloadData()
    }

    override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        if segue!.identifier == "DetailsExcercise" {
            // And finally, when launching the child view,
            // make sure to set the delegate.
            let viewController = segue!.destinationViewController as DetailsExerciseViewController
            viewController.delegate = self
        }
    }
}

尽管如此,在单击“后退”按钮时尝试保存数据似乎是不标准的。您确定不想改为在“完成”时执行此操作吗?

当您按下后退按钮时,导航控制器将调用
导航控制器(willShowViewController:)
,以便您可以使用此按钮将数据传递回初始视图控制器。示例如下所示:

使用
UINavigationControllerDelegate

class DetailsViewController: UIViewController, UINavigationControllerDelegate {
                                                        //     ^
    var data: [String] = []                             // Important!

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.delegate = self

        data = ["data has changed!"]
    }
}
extension DetailsViewController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        (viewController as? ProgressTableViewController)?.data = data // Here you pass the to your original view controller
    }
}
class Data {
    var array: [String] = []
}
class ProgressTableViewController: UITableViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["some data"]
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.array.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        cell.textLabel?.text = data.array[indexPath.row]

        return cell
    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "exerciseSegue" {
            let destination = segue.destinationViewController as! DetailsViewController
            destination.data = data
        }
    }
}
class DetailsViewController: UIViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["data has changed!"]
    }
}
Swift 2:

extension DetailsViewController: UINavigationControllerDelegate {
    func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        if let controller = viewController as? ProgressTableViewController {
            controller.data = data    // Here you pass the data back to your original view controller
        }
    }
}
Swift 3:

class DetailsViewController: UIViewController, UINavigationControllerDelegate {
                                                        //     ^
    var data: [String] = []                             // Important!

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.delegate = self

        data = ["data has changed!"]
    }
}
extension DetailsViewController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        (viewController as? ProgressTableViewController)?.data = data // Here you pass the to your original view controller
    }
}
class Data {
    var array: [String] = []
}
class ProgressTableViewController: UITableViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["some data"]
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.array.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        cell.textLabel?.text = data.array[indexPath.row]

        return cell
    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "exerciseSegue" {
            let destination = segue.destinationViewController as! DetailsViewController
            destination.data = data
        }
    }
}
class DetailsViewController: UIViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["data has changed!"]
    }
}
在本例中,按键使用
UINavigationControllerDelegate
并设置导航控制器的委托(在本例中为
self
)。完成此操作后,可以使用“后退”按钮将数据发送回初始视图控制器

就我个人而言,我更喜欢使用类来处理我的数据:

为数据使用自定义类:

class DetailsViewController: UIViewController, UINavigationControllerDelegate {
                                                        //     ^
    var data: [String] = []                             // Important!

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.delegate = self

        data = ["data has changed!"]
    }
}
extension DetailsViewController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        (viewController as? ProgressTableViewController)?.data = data // Here you pass the to your original view controller
    }
}
class Data {
    var array: [String] = []
}
class ProgressTableViewController: UITableViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["some data"]
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.array.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        cell.textLabel?.text = data.array[indexPath.row]

        return cell
    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "exerciseSegue" {
            let destination = segue.destinationViewController as! DetailsViewController
            destination.data = data
        }
    }
}
class DetailsViewController: UIViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["data has changed!"]
    }
}
进度视图控制器:

class DetailsViewController: UIViewController, UINavigationControllerDelegate {
                                                        //     ^
    var data: [String] = []                             // Important!

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.delegate = self

        data = ["data has changed!"]
    }
}
extension DetailsViewController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        (viewController as? ProgressTableViewController)?.data = data // Here you pass the to your original view controller
    }
}
class Data {
    var array: [String] = []
}
class ProgressTableViewController: UITableViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["some data"]
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.array.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        cell.textLabel?.text = data.array[indexPath.row]

        return cell
    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "exerciseSegue" {
            let destination = segue.destinationViewController as! DetailsViewController
            destination.data = data
        }
    }
}
class DetailsViewController: UIViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["data has changed!"]
    }
}
详细信息视图控制器:

class DetailsViewController: UIViewController, UINavigationControllerDelegate {
                                                        //     ^
    var data: [String] = []                             // Important!

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.delegate = self

        data = ["data has changed!"]
    }
}
extension DetailsViewController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        (viewController as? ProgressTableViewController)?.data = data // Here you pass the to your original view controller
    }
}
class Data {
    var array: [String] = []
}
class ProgressTableViewController: UITableViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["some data"]
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.array.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        cell.textLabel?.text = data.array[indexPath.row]

        return cell
    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "exerciseSegue" {
            let destination = segue.destinationViewController as! DetailsViewController
            destination.data = data
        }
    }
}
class DetailsViewController: UIViewController {

    var data = Data()

    override func viewDidLoad() {
        super.viewDidLoad()

        data.array = ["data has changed!"]
    }
}

在上一个示例中,您不必担心数据的传递。每当您更改数据时,使用同一类的控制器也将进行更改。

更简单的解决方案您可以使用self.navigationController?.viewControllers访问以前的视图控制器,如下所示:

let vcsCount = self.navigationController?.viewControllers.count
self.navigationController?.viewControllers[vcsCount! - 2].updateData

updateData是要在上一个view controller更新的数据成员。此外,您可以使用此扩展:

extension UINavigationController {
    func viewController<T: UIViewController>(class: T.Type) -> T? {

        return viewControllers.filter({$0 is T}).first as? T
    }
}

//

if let controller = navigationController?.viewController(class: MainViewController.self) {
     controller.data = data
}

navigationController?.popViewController(animated: true)
扩展UINavigationController{ func viewController(类:T.Type)->T{ 返回viewControllers.filter({$0是T}) } } // 如果let controller=navigationController?.viewController(类:MainViewController.self){ controller.data=数据 } navigationController?.popViewController(动画:true)
感谢您回答我的问题,但您的代码根本无法理解!在
func detailswilldemouse
中,如何将数据传递回父视图??您在何处初始化historyView?请记住,您的类
detailseerciseViewController
将有一个强大的引用循环,因为委托将阻止它被释放。使其
将解决这个问题。正如@Eendje在他的评论中所说的,您需要使用弱引用来实现委托,以避免任何错误cycle@Eendje对不起,我是新的协议和代表,请你回答我的问题与一些代码的例子来解决我的问题。非常感谢你!而不是传递它,你也可以考虑创建一个自定义类,将数组作为类属性,所以每当你在练习视图控制器中更改它们时,它们也会在进度视图控制器中改变。非常感谢你!今天学了一件新东西。非常感谢,伊恩杰:)为什么投反对票?我想知道,这样我可以纠正它。我喜欢第一个例子!在我从扩展中删除冗余的
UINavigationControllerDelegate
后,第一个示例就成功了。