将数据从屏幕传递到屏幕xcode?

时间:2017-04-19 01:35:24

标签: ios swift viewcontroller

我在ViewController1

中有这个代码
var calendarios = [Calendario]()
var totalCalendarios1 = 0

(当屏幕加载totalCalendarios更改并且它正确显示总数时,我可以在调试中看到它) 我希望它传递给我的ViewController2,我已经制作了这段代码:

let copiaCalendarios = ViewController1()
let totalCalendarios2 = copiaCalendarios.totalCalendarios1

我打印了第二个值并且它表示0,总是,它之前并不重要。

我也使用过这段代码:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destino = segue.destination as? ViewController
        destino?.calendariosCopia = calendarios
    }

但不起作用。 我究竟做错了什么? 已搜索信息,但它已过时

编辑: 这是我的原始代码: CalendarioViewController是我的第二个VC,CalendarioTableViewController是我的第一个VC并且是发送者。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destino = segue.destination as? CalendarioViewController
        destino?.calendariosCopia = calendarios
    }

这是我使用的代码,也是这个代码:

let copiaCalendarios = CalendarioTableViewController()
let totalCalendarios = copiaCalendarios.totalCalendarios
两个VC中的

都有一个var totalCalendarios = 0

感谢先生,对不起我的坏英语:$

EDIT2: 这种segue是否重要? 因为我使用过#Mod;'

EDIT3: CalendarioTableViewController:

//
//  CalendarioTableViewController.swift
//  Vizion5
//
//  Created by ROB on 16/04/17.
//  Copyright © 2017 ROB. All rights reserved.
//

import UIKit

class CalendarioTableViewController: UITableViewController {

    var calendarios = [Calendario]()
    var totalCalendarios = 0

    func cargarEjemplos() {

        guard let calendario1 = Calendario(nombre: "2017-A", fin: "17/01/2017", inicio: "05/05/2017") else {
            fatalError("Error en calendario table view controller")
        }

        guard let calendario2 = Calendario(nombre: "2016-A", fin: "17/01/2016", inicio: "05/05/2016") else {
            fatalError("Error en calendario table view controller")
        }

        calendarios += [calendario1, calendario2]

    }

    func contarCalendarios() {
        totalCalendarios = calendarios.count
    }

    //AÑADIDO AUTOMATICAMENTE

    override func viewDidLoad() {
        super.viewDidLoad()

        //CARGA LOS EJEMPLOS
        cargarEjemplos()
        contarCalendarios()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //let identificadorCelda = "tablaCalendario"
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "tablaCalendario", for: indexPath) as? CalendarioTableViewCell
            else {
                fatalError("error 1: calendario table controller")
        }

        let calendario = calendarios[indexPath.row]

        // Configure the cell...

        cell.nombreCalendario.text = calendario.nombre
        cell.finCalendario.text = calendario.fin
        cell.inicioCalendario.text = calendario.inicio

        return cell
    }

    //MARK: ACCIONES
    @IBAction func regresarATablaCalendario(sender: UIStoryboardSegue) {
        if let viewControllerOrigen = sender.source as? CalendarioViewController, let calendario = viewControllerOrigen.calendario {
            //AÑADE EL NUEVO CALENDARIO
            let newIndexPath = IndexPath(row: calendarios.count, section: 0)
            calendarios.append(calendario)
            tableView.insertRows(at: [newIndexPath], with: .automatic)
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        print("Total calendarios es: " + String(totalCalendarios))
        let destino = segue.destination as? CalendarioViewController // here you have to use the exact name of your Second View Controller instead of ViewController
        destino?.totalCalendarios = totalCalendarios
    }

}

我的CalendarioViewController

//
//  CalendarioViewController.swift
//  Vizion5
//
//  Created by ROB on 16/04/17.
//  Copyright © 2017 ROB. All rights reserved.
//

import UIKit

class CalendarioViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var nombreCalendario: UITextField!
    @IBOutlet weak var fechaInicioCalendario: UIDatePicker!
    @IBOutlet weak var fechaFinCalendario: UIDatePicker!
    @IBOutlet weak var botonGuardar: UIBarButtonItem!

    var totalCalendarios = 0

    //ESTE VALOR SERA PASADO POR 'CALENDARIOVIEWCONTROLLER' EN 'PREPARE(FOR: SENDER:)' O CONTRUIDO PARA AGREGAR UN NUEVO CALENDARIO
    var calendario: Calendario?

    override func viewDidLoad() {
        super.viewDidLoad()
        nombreCalendario.delegate = self //SE CONTROLA A SI MISMO

        print("Total segue: " + String(totalCalendarios))

        //CHECA SI SE PUEDE HABILITAR EL BOTON DE GAURDADO
        //DESABILITA EL BOTON DE GUARDADO
        botonGuardar.isEnabled = false
        //actualizaEstadoBotonGuardar()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //MARK: FUNCIONES DE TECLADO Y DETERMINAR FECHA (QUE EL FIN SEA MAYOR QUE INICIO)

    func textFieldDidBeginEditing(_ textField: UITextField) {
        botonGuardar.isEnabled = false
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        //SE DESHABILITA EL BOTON DE GUARDAR CUANDO SE ESCRIBE
        botonGuardar.isEnabled = false
        //ESCONDE EL TECLADO AL PRESIONADO "HECHO" (DONE)
        textField.resignFirstResponder()
        return true
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        actualizaEstadoBotonGuardar()
        //navigationItem.title = textField.text
    }


    // MARK: - NAVEGACION (UNWIND SEGUE)
    @IBAction func botonCancelar(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
    }

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        //super.prepare(for: segue, sender: sender)
        guard let button = sender as? UIBarButtonItem, button === botonGuardar else {
            print("Error en prepare sender")
            return
        }

        let setFormatoFecha = DateFormatter()
        setFormatoFecha.dateFormat = "dd/MM/yyyy"

        let nombre = nombreCalendario.text
        let fin = setFormatoFecha.string(from: fechaFinCalendario.date)
        let inicio = setFormatoFecha.string(from: fechaInicioCalendario.date)

        //SE INSERTAN LOS DATOS LEIDOS.
        calendario = Calendario(nombre: nombre!, fin: fin, inicio: inicio)

        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }

    //MARK: METODOS PRIVADOS

    private func actualizaEstadoBotonGuardar() {
        //DESHABILITA EL BOTON DE GUARDAR CUANDO ESTA EN BLANCO *WIP*
        let texto = nombreCalendario.text ?? ""
        let tieneTexto = !texto.isEmpty

        //WIP
        if (!texto.isEmpty) {
            if (fechaInicioCalendario.date >= fechaFinCalendario.date) {
                botonGuardar.isEnabled = false
            } else {
                botonGuardar.isEnabled = true
            }
        }
    }

}

2 个答案:

答案 0 :(得分:0)

让我知道我错在哪里,你的代码对我来说有点混乱。 (我会编辑。)

您的totalCalendarios1ViewController1实例中的值。在我看来,您希望将此值传递给ViewController2,并传递给名为totalCalendarios2的变量。

首先,你有一个(小)错误:

let totalCalendarios2 = copiaCalendarios.totalCalendarios

不应该是totalCalendarios1吗? (这是我对您的命名约定感到困惑的地方。希望这可能是一个语言问题,或者您将代码简化为打字错误。)

无论如何,这是一个小问题。 真实问题与您的segue代码有关。这就是你要纠正的地方。

假设您有以下内容:

<强> ViewController1:

var totalCalendarios:Int = 0

<强> ViewController2

var totalCalendarios:Int = 0

现在在ViewController1中,此变量更新为不同的值,可能是2017,并且您希望将此值传递给ViewController2。所有你需要的 - 只要你定义了一个segue - 是:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "MySegueName" {
        if let vc = segue.destination as? ViewController2 {
            vc.totalCalendarios = totalCalendarios
        }
    }
}

与发布的代码相比,最大的错误是将目标VC转换为ViewController而不是ViewController2。我看到了其他潜在问题,但是你的变量不足以让我知道它们是否也是一个问题。

总结:

  • 除非您根本无法保持变量名称相同,否则视图控制器之间的命名方式没有问题。事实上,它可以帮助其他人理解您的代码。
  • 如果您使用的是segue,则无需实例化任何视图控制器。但是你应该在 prepare(对于segue:)强制目标VC。
  • 演员表之后,只需传递变量。

答案 1 :(得分:0)

我假设您的班级名称是ViewController1,如您所说。没关系。但是你是如何过去let totalCalendarios2 = copiaCalendarios.totalCalendarios的?这是一个错字还是你真的在你的代码中写了这一行?它应该是:

let totalCalendarios2 = copiaCalendarios.totalCalendarios1

好吧,如果你真的想要将数据从一个屏幕传递到另一个屏幕(实际上它是另一个控制器的一个控制器),请按照:

  1. 在您的第一个视图控制器中(从您要传递的位置),具有您要传递的数据类型的属性。对于你的情况:

    var totalCalendarios = 0
    

    现在根据您的需要更新此totalCalendarios

  2. 要使用segue传递数据,您需要在 Interface Builder (从源控制器到目标控制器)中添加一个segue并将其赋予segue一个名字。我们说 CalenderSegue

  3. 在第二个视图控制器中(要传递到的位置),您需要具有您从第一个传递的数据的确切类型的属性。在你的情况下它是Int。因此,在第二视图控制器中声明一个属性:

    var totalCalendarios = 0
    
  4. 现在使用此

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let identifier = segue.identifier, identifier = "CalenderSegue" { 
            let destino = segue.destination as? CalendarioViewController // here you have to use the exact name of your Second View Controller instead of ViewController
            destino?.totalCalendarios = totalCalendarios
        }
    }
    
  5. 修改:1

    CalendarioViewController课程中删除这些行(您无需为CalendarioTableViewController创建对象)

    let copiaCalendarios = CalendarioTableViewController()
    let totalCalendarios = copiaCalendarios.totalCalendarios
    

    将此添加到CalendarioViewController

    var totalCalendarios = 0
    

    并使用上面的prepare(for segue: UIStoryboardSegue, sender: Any?)方法。

      

    但是如果你只有一个segue并且已经添加了它   TableViewCellCalendarioViewController然后您可以使用

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
        let destino = segue.destination as? CalendarioViewController // here you have to use the exact name of your Second View Controller instead of ViewController
        destino?.totalCalendarios = totalCalendarios
    }
    

    修改:2

    segue可能存在问题。从segue中删除所有TableViewCell,然后将其添加回来。如果您不知道该怎么做,请参阅此image