【问题标题】:Passing variables as NSDict from Viewcontroller to Viewcontroller将变量作为 NSDict 从 Viewcontroller 传递到 Viewcontroller
【发布时间】:2016-11-17 09:26:10
【问题描述】:

我有一个简单的注册故事板,询问用户他们的姓名等。我正在将输入的数据收集为 UITextfields,并希望将它们全部传递给最终的视图控制器,在那里我将其全部设为数组并将其发送到服务器。 JSON 但在添加测试数据时一切正常。

基础视图控制器

   struct NewUserStruct {
    var firstName: String
    var lastName: String
}

发送VC

let firstNameReg = inputFirstName.text
    let lastNameReg = inputLastName.text

    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destVC = segue.destination as? RegistrationUpdateViewController {
            let newuser = NewUserStruct(firstName: firstNameReg! , lastName: lastNameReg! )
            print(newuser)
            destVC.newuser = newuser
        }        }

和接收VC

var newuser: NewUserStruct?
func createUser(){

guard let user = self.newuser else {
print("User is not set")
return
}

let service = "registration"
let parameters: [String: Any] = ["firstName": user.firstName,
                                 "lastName": user.lastName,
                                 "email": "Johnsmith@test11.com",
                                 "password": "12345678",
                                 "region": "EU",
                                 "bundleId":    Bundle.main.bundleIdentifier!,
                                 "appVersion": Bundle.main.infoDictionary?["CFBundleVersion"] as! String]

这可以编译,但我得到的 print(newuser) 值为 nil,它会打印保护 "User is not set"

这是我的整个 VC

import Foundation
import UIKit

class RegistrationNameViewController: BaseViewController {

@IBOutlet var inputFirstName: UITextField!
@IBOutlet var inputLastName: UITextField!



override func setup() {

}

override func navbarTitle() -> String {
    return "Name"
}

override func leftNavbarButtonType() -> NavbarButtonType {
    return NavbarButtonType.eNavbarButtonTypeBack
}

override func rightNavbarButtonType() -> NavbarButtonType {
    return NavbarButtonType.eNavbarButtonTypeNext

}

override func navbarViewNextPressed(_ navbarView: NavbarView) {
    let firstNameReg = inputFirstName.text
    let lastNameReg = inputLastName.text
    print(inputFirstName.text!,inputLastName.text!)

    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destVC = segue.destination as? RegistrationUpdateViewController {
            print(destVC)
            let newuser = NewUserStruct(firstName: firstNameReg! , lastName: lastNameReg! )
            print(newuser)
            destVC.newuser = newuser
        }        }
    self.performSegue(withIdentifier: "NameToEmail", sender: nil)

}


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

}

【问题讨论】:

  • 既然你使用的是 Swift,你应该使用 Dictionary,而不是 NSDictionary。您的接收字典似乎是 NameVars 而不是 Name2Array。你不应该用大写字母命名变量,你应该使用结构而不是字典来传递数据
  • 我更改了名称,因为我最终将有更多变量进入最终视图控制器。我想我应该有一行 let let Name2Array : NSDictionary = self.receiveItem 然后 let NameVars : NSDictionary = self.receiveItem 我还会更改大写字母。有理由使用结构而不是字典吗?我不完全理解这些差异。我正在使用现有代码,这就是它的 NSDictionary 而不是 Dictionary 的原因。谢谢!
  • 字典的问题在于它不精确;你需要知道键值,如果你犯了一个简单的打字错误,那么事情就会中断。如果您使用结构,则编译器将提供自动完成功能,并且更明确地定义了属性是什么。 NSDictionary 被桥接到一个 swift 字典
  • var sendItem: NSDictionary! var receiveItem:NSDictionary!这是在我的 BaseViewcontroller 中。要将其更改为 Struct 需要我制作一个空白,对吗?然后我可以使用点语法来附加值吗?
  • 另外,您如何将值分配给 receiveItem ?你在使用prepare(for:) 吗?

标签: ios swift swift3


【解决方案1】:

我会使用一个结构体,这样您就可以正确定义所传递的数据。

struct NewUser {
    var firstName: String
    var lastName: String
}

现在您可以创建此结构的实例并将其传递给prepare(for segue:) 中的目标视图控制器

override func navbarViewNextPressed(_ navbarView: NavbarView) {
    guard let firstName = inputFirstName.text where !firstName.isEmpty
          let lastName = inputLastName.text where !lastName.isEmpty else {
        print("first name and last name are required")
        return
    }

    let newUser = NewUser(firstName: firstName, lastName: lastName) 

    self.performSegue(withIdentifier: "NameToEmail", sender: newUser)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destVC = segue.destination as? RegistrationUpdateViewController {
        print(destVC)
        if let newuser = sender as? NewUser {  
            print(newuser)
            destVC.newuser = newuser
        }
    }
}

在您的目标视图控制器中:

class RegistrationUpdateViewController {
    var user: NewUser?

    func someFunction {
        guard let user = self.user else {
            print("User is not set")
            return
        }

        let service = "registration"
        let parameters: [String: Any] = ["firstName": user.firstName,
                                        "lastName": user.lastName,
                                        "email": "Johnsmith@test11.com",
                                        "password": "12345678",
                                        "region": "EU",
                                        "bundleId":    Bundle.main.bundleIdentifier!,
                                        "appVersion": Bundle.main.infoDictionary?["CFBundleVersion"] as! String] 
    ...
    }

}

【讨论】:

  • 感谢!
  • 我离得很近。我当前的问题是我的 Viewcontroller 有这个, let firstNameReg = inputFirstName.text let lastNameReg = inputLastName.text let newuser = NewUser(firstName: firstNameReg!, lastName: lastNameReg!) print(newuser) print(NewUser.self) 它打印newuser 很好,但 NewUser 为零。当代码在接收的 VC 中运行时,它会遇到“未设置用户”作为它的 nil 吗?迷茫的脸。 (必须像在 baseviewcontroller 中使用 User 一样重命名为 NewUser!)
  • 听起来您没有在目标视图控制器中分配属性。你准备好运行 segue 代码了吗?
  • 它不喜欢 destVC.newuser = NewUser 给出错误“无法将类型 baseviewcontroller.NewUser.Type 的值分配给类型 baseviewcontroller.NewUser?”
  • 你想要newUser 而不是NewUser - 这就是为什么坚持变量的小写字母和类/结构的大写字母的约定很重要——它有助于避免这种错误.
猜你喜欢
  • 1970-01-01
  • 2014-07-25
  • 2017-11-08
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多