从另一个类中的 UITextField 访问文本

Posted

技术标签:

【中文标题】从另一个类中的 UITextField 访问文本【英文标题】:Access text from a UITextField in another class 【发布时间】:2016-08-11 12:43:37 【问题描述】:

我想在一个单独的类中从UITextField 中提取用户输入文本,以便将其保存到我的解析数据库中。当我尝试保存数据库时,名称字符串显示为空。

我正在从这个视图控制器中提取文本

class ProfileViewController: UIViewController, UITextFieldDelegate 


@IBOutlet weak var name: UITextField!
var newName = String()

@IBAction func DropLocation(sender: AnyObject)
    SaveName().setporta()

我想用这个类保存它

class SaveName: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate

var user = PFUser.currentUser()?.username
var ad = PFObject(className:"Post")
var query = PFQuery(className:"Post")
var name = String()


func setporta() 
    name = ProfileViewController().name!.text!

    query.whereKey("user", equalTo: user!)
    query.getFirstObjectInBackgroundWithBlock() (uobject: PFObject?, error: NSError?) -> Void in
        if error != nil 
            self.ad["name"] = self.name ?? NSNull()
            self.ad.saveInBackground()
         else if let uobject = uobject
            uobject["name"] = self.name ?? NSNull()
            uobject.saveInBackground()
        
    

关于如何使用 SaveName 类进行保存有什么建议吗?

【问题讨论】:

你是如何从 ProfileViewController 转换到 SaveName 的?? 是的,很抱歉我修复了它。在Xcode项目中是正确的 我正在用一个按钮调用那个类。我更新了 ProfileViewController 以显示这一点。 我很惊讶ProfileViewController().name! 没有崩溃。您正在创建一个新对象而不加载其出口。 我还建议您研究 MVC 结构,这将引导您将数据管理移出视图控制器的想法。 【参考方案1】:

我认为你应该稍微改变一下你的方法,比如:

func setporta(nameFromtextField:String) 
    name = nameFromtextField
//rest of the code
.
.
.

然后像这样调用你的方法:

SaveName().setporta(name!.text!)

【讨论】:

【参考方案2】:

发生的情况是,在 SaveName 中,您没有使用实际的 ProfileViewController。您正在创建ProfileViewController新实例

这就是你出错的地方;

Name = ProfileViewController().name!.text!

ProfileViewController() 创建一个新实例,其中有一个新的name UITextField,当然是空的,因为它是新的。

相反,假设您的原始 ProfileViewControllerSaveName 都在同一个 UINavigationController 中,您可以尝试通过查看 viewControllers 属性来访问原始 UITextField。

例如(伪代码且未勾选,请勿复制粘贴此);

func setporta() 
    // At what index is the current view controller?
    let currentIndex = self.navigationController.viewControllers.indexOf(self)

    // Get the original ProfileViewController
    let profile = self.navigationController.viewControllers[currentIndex]

    // Get the text from the filled in UITextField
    name = profile.name!.text!

... snipped ...


但是,这是一种糟糕的形式并且难以维护,因为 ViewController 应该尽可能少地了解彼此。相反,当您将SaveName 推送到屏幕上时,您应该首先传递ProfileViewController 的文本字段条目。以后不要访问它。

【讨论】:

我基本上同意你的看法,但是因为他也在做SaveName().setporta()(更多的对象初始化),它变得更加陌生。【参考方案3】:

嗯, 你写的事实: Name = ProfileViewController().name!.text!

实际上创建一个 ProfileViewController 并尝试获取名称,这是一个空字符串,因为您没有呈现屏幕,因此用户无法输入它。

所以你想做的是: - 呈现 ProfileViewController - 让用户在文本字段中输入他们的名字 - 在按下确定按钮或其他任何东西时,从配置文件视图控制器获取文本。

展示 ProfileViewController

您可以从您的 SaveName 类中使用(不幸的是,ViewController 的子类名称应该以 ViewController 结尾):

[self presentViewController:[[ProfileViewController alloc]init] 动画:是 完成:无];

2- 让用户在文本字段中输入他们的姓名

这里没什么可做的。

3- 找回名字

这样做的最佳方式是使用委托模式,但是,在 swift 中,您还不如向视图控制器添加一个闭包,以便它知道单击确定/取消按钮时该做什么,并设置它在展示视图控制器之前。

结果大概是:

    class ProfileViewController: UIViewController 

        var completionHandler:((name:String)->Void)?

    @IBOutlet weak var name: UITextField!

    // var newName = String() // useless...

    // Call this when user is done typing is name...
    func onOKButtonClicked() -> Void
    
        if let c = completionHandler
        
            c(name:name.text!);
        
    



class SaveName: UIViewController

    /* ... */

    func presentProfileViewController() -> Void
    
        let pvc = ProfileViewController();
        pvc.completionHandler =  name in

            self.recordName(name);

        
        self.presentViewController(pvc, animated:true, completion: nil);
    

    func recordName(name: String) -> Void
    
        // send name to parse...
    

【讨论】:

【参考方案4】:

所以也许我在提问方面很糟糕,但我的解决方案是这样的。

var newName = String()
class ProfileViewController: UIViewController, UITextFieldDelegate 

@IBOutlet weak var name: UITextField!


@IBAction func DropLocation(sender: AnyObject)
newName = name.text!
SaveName().setporta()

然后我的 DropLoc 类看起来像这样

class SaveName: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate

var user = PFUser.currentUser()?.username
var ad = PFObject(className:"Post")
var query = PFQuery(className:"Post")


func setporta() 
name = ProfileViewController().name!.text!

query.whereKey("user", equalTo: user!)
query.getFirstObjectInBackgroundWithBlock() (uobject: PFObject?, error: NSError?) -> Void in
    if error != nil 
        self.ad["name"] = name ?? NSNull()
        self.ad.saveInBackground()
     else if let uobject = uobject
        uobject["name"] = name ?? NSNull()
        uobject.saveInBackground()
    
  

感谢所有回复希望这可以帮助其他人坚持这一点。

【讨论】:

以上是关于从另一个类中的 UITextField 访问文本的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 点击​​后从 UITextfield 捕获文本

我如何使用Combine来跟踪UIViewRepresentable类中的UITextField更改?

如何从另一个线程更新 GUI 上的文本框 [重复]

从主视图控制器访问模态视图控制器中的 UITextField 中的文本

从另一个类访问 IBOutlet

如何访问在其他类中的一个类中定义的小部件,而不会看到重新定义的图形界面