我正在尝试创建一个iOS应用程序,它从文本字段中获取用户名,将其转换为字符串并将其传递给另一个名为HomeModel.swift的文件。这个文件是不一个ViewController,但我需要将该变量名添加到一个URL。
目前,我的应用程序设置了一个初始视图控制器,其中包含用户名和登录按钮的文本字段。当我单击登录按钮时,它将获取文本字段条目并将其转换为字符串,然后我将其用于在下一个ViewController上转换为标签。我的问题是将用户名变量(我以前变成标签)并将其传递给非ViewController swift文件,这样我就可以用它做一些“幕后”的东西。
任何帮助都会非常感激,因为我花了好几个小时试图找到一个答案,但却出现了短暂的问题。
这是我最初的ViewController
import UIKit
class Home: UIViewController, UITextFieldDelegate {
@IBOutlet var TextField: UITextField!
@IBOutlet var PasswordField: UITextField!
@IBOutlet var LoginBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.TextField.delegate = self
self.PasswordField.delegate = self
func checkField(sender: Any?) {
if (TextField.text?.isEmpty)! || (PasswordField.text?.isEmpty)!
{
LoginBtn.isEnabled = false
}
else
{
LoginBtn.isEnabled = true
}
}
}
//Hide keyboard when touched outisde keyboard
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
PasswordField.resignFirstResponder()
return (true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let DestViewController : ViewTwo = segue.destination as! ViewTwo
DestViewController.PasswordText = PasswordField.text!
DestViewController.LabelText = TextField.text!
}
}
这是HomeModel.swift文件
import Foundation
protocol HomeModelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class HomeModel: NSObject, URLSessionDataDelegate {
//properties
weak var delegate: HomeModelProtocol!
func viewDidLoad() {
}
func downloadItems() {
let myusername = //Variable from initial controller here
let urlPath = "http://urlhere.com/index.php?username="+myusername //this is where the list of users are
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) { (data, response, error) in
if error != nil {
print("Failed to download data")
}
else {
print("Contact List Data Downloaded")
self.parseJSON(data!)
}
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
print (jsonResult)
do {
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
}
catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let locations = NSMutableArray()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let location = LocationModel()
//the following insures none of the JsonElement values are nil through optional binding
if let name = jsonElement["name"] as? String,
let phone = jsonElement["phone"] as? String
{
location.name = name
location.phone = phone
}
locations.add(location)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: locations)
})
}
}
答案 0 :(得分:1)
通常根据您的描述,这只是在您拥有的视图控制器之间传递对象。假设有:
class LoginData {
var username: String?
}
现在你的第一个视图控制器似乎是你的入口点,所以它就是那个创建它的人,例如&#34; next&#34;按下按钮。然后应该将此对象传递给新的视图控制器:
@IBAction onNextPressed() {
let loginData = LoginData() // Create object
loginData.username = self.textField.text // Set data to it
let nextController = UIStoryboard(...) as! NextViewController // Generate new view controller
nextController.loginData = loginData // Assign login data
navigationController.push(... nextController ...) // Show controller
}
那么下一个视图控制器应该使用这个对象:
class NextViewController: UIViewController {
var loginData: LoginData?
override func viewDidLoad() {
super.viewDidLoad()
self.label.text = loginData?.username
}
...
在某些情况下(看起来像你的),全局保存数据可能是有意义的。要做到这一点,您只需要一个静态变量。在您的情况下,我建议您创建一个新对象User
。
class User {
static var current: User?
var loginData: LoginData?
}
现在这里User
只包含登录数据,但是还有一个占位符来添加当前用户的实例,可以在应用程序内部使用。
现在对于这种情况,第一个视图控制器不需要将数据传递给下一个视图控制器,而是设置当前用户:
@IBAction onNextPressed() {
let loginData = LoginData() // Create object
loginData.username = self.textField.text // Set data to it
let newUser = User() // Create a new user
newUser.loginData = loginData // Assign login data to it
User.current = newUser // Set current user
let nextController = UIStoryboard(...) // Generate new view controller
navigationController.push(... nextController ...) // Show controller
}
新视图控制器不需要对登录数据的引用:
class NextViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.label.text = User.current?.loginData?.username
}
...
当您需要在整个应用中使用这些数据时,这非常棒,因为您提到了一些网址,如果您实施,您现在可以在任何地方User.current?.serviceURL
拨打电话:
extension User {
var serviceURL: URL? {
guard let username = username else {
return nil
}
return URL(string: "https://some.pat/\(username)/resource_name")
}
}
我希望这清除了一些关于在Swift中传递数据的事情。