【问题标题】:Save text in array and display in a table view将文本保存在数组中并在表格视图中显示
【发布时间】:2016-01-18 17:41:36
【问题描述】:

我正在尝试创建一个基于字符串数组显示表格视图的应用程序。

我有一个视图控制器和一个较小的内容视图。在视图控制器中有一个文本字段和一个按钮,应该将写入的文本保存在一个数组中并在表格视图控制器中显示它。以及将其嵌入到内容视图中。

我不知道如何保存写入的文本并将其添加到数组中,可能使用追加。

如何在表格视图中显示数组并将数组保存在 NSUserDefaults 中?

编辑: 这是视图控制器和内容视图的图像。我想在文本字段中插入一个字符串(绿色按钮 Save 上的那个),然后我点击绿色按钮,我写的字符串被添加到数组中并显示在嵌入的表视图控制器的表视图单元格中内容视图。同时,文本字段返回空,但我已经知道如何清除它。然后,我可以在文本字段中重写文本,它应该重复我刚才描述的操作。 保存在 NSUserDefaults 中的时刻并不那么重要。 谢谢您的帮助。 :)

http://i.stack.imgur.com/z5uTc.png

编辑 2:

主VC

import UIKit

class mainVC: UIViewController {
@IBOutlet var txtField: UITextField!
var embTableVC: tableVC!

override func viewDidLoad() {
    super.viewDidLoad()
 // Do any additional setup after loading the view.
}

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

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "embededTableVC" {
        embTableVC = segue.destinationViewController as! tableVC
    }
}

@IBAction func Save() {
    if let Text = txtField.text {
        if txtField.text == "" {
            myArray.append(Text)
            let row = myArray.count-1
            let indexPath = NSIndexPath(forRow: row, inSection: 0)
            embTableVC.myTableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }
    }
 txtField.text = ""
    txtField.resignFirstResponder()
}     
}

表VC

  import UIKit

  var myArray = [String]()

  class tableVC: UITableViewController {
  @IBOutlet var myTableView: UITableView! {
    didSet {
        myTableView.dataSource = self
        myTableView.delegate = self
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    myTableView.dataSource = self
    myTableView.delegate = self
    myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "customcell")
    // Do any additional setup after loading the view, typically from a nib.

}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    myTableView.reloadData()
}

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

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

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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = myTableView.dequeueReusableCellWithIdentifier("customcell", forIndexPath: indexPath) as UITableViewCell

    cell.textLabel?.text = myArray[indexPath.item]

    return cell
}

非常感谢:)

【问题讨论】:

  • 您能否详细说明您希望按什么顺序发生的事情?或许还有你故事板的截图?
  • 查看编辑,非常感谢:)

标签: arrays swift uitextfield


【解决方案1】:

存储信息:

// Get the standardUserDefaults object, store your UITableView data array against a key, synchronize the defaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:arrayOfImage forKey:@"tableViewDataImage"];
[userDefaults setObject:arrayOfText forKey:@"tableViewDataText"];
[userDefaults synchronize];

要检索信息:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayOfImages = [userDefaults objectForKey:@"tableViewDataImage"];
NSArray *arrayOfText = [userDefaults objectForKey:@"tableViewDataText"];
// Use 'yourArray' to repopulate your UITableView
On first load, check whether the result that comes back from NSUserDefaults is nil, if it is, you need to create your data, otherwise load the data from NSUserDefaults and your UITableView will maintain state.

在 Swift 中,可以使用以下方法:

let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(arrayOfImage, forKey:"tableViewDataImage")
userDefaults.setObject(setObject:arrayOfText, forKey:"tableViewDataText")
userDefaults.synchronize()

var arrayOfImages = userDefaults.objectForKey("tableViewDataImage")
var arrayOfText = userDefaults.objectForKey("tableViewDataText")

希望这会有所帮助。您还可以使用 xcdatamodeld 来保存和检索数据。

【讨论】:

  • 谢谢,您不知道如何从文本字段中将文本保存在数组中吗?:)
  • 你应该能够做这样的事情来将它发送到一个数组。只需将此添加到 viewDidLoad: 方法,它应该可以正常工作: textFieldArray = [[NSMutableArray alloc]init];
【解决方案2】:

这是一个将文本存储在数组中的简单解决方案,如果您可能有大量字符串,这是比 NSUserDefaults 更好的选择。

首先,您需要在视图控制器中拥有一个字符串数组来管理表视图。然后,您将需要一种访问该数组并对其进行编辑的方法。

我会将对表视图控制器的引用存储在第一个视图控制器中(使用容器)。要首先设置此引用,请使用嵌入转场。

在您的故事板中,将第一个 VC 连接到表 VC 的箭头实际上是一个嵌入转场,在加载容器视图时触发。点击 segue,在 Xcode 的属性检查器中将标识符更改为一些字符串,例如“embedTableVC”。

然后我们可以在第一个视图控制器中设置引用。下面是一些相关代码,假设带有容器的视图控制器有一个 MainViewController 类,容器内的表视图控制器有一个 TableViewController 类:

class MainViewController: UIViewController {

    var embededTableVC: TableViewController!

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "embedTableVC" {
            embededTableVC = segue.destinationViewController as! TableViewController
        }
    }

}

一旦主视图控制器加载,容器将被加载,这将导致 segue 运行,这将导致 prepareForSegue 被调用。在这个实现中,我们将表视图控制器存储在主视图控制器的一个属性中,以便我们可以访问它。由于类是引用类型,因此该属性将引用同一个对象,而不是副本。

然后,一旦按下保存按钮,您就会从文本字段中获取文本,并将其设置到表 VC 中的数组中,如下所示:

@IBAction func save() {
    if let text = textField.text {
        if text != "" {
            embededTableVC.valueArray.append(text)
            // and if you want to go ahead and add it to the array from here instead of using delegation or notification observance
            let row = embededTableVC.valueArray.count - 1
            let indexPath = NSIndexPath(forRow: row, inSection: 0)
            tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }
    }
}

if-let 语法确保文本字段的文本属性不为零。

我相信这就是您要寻找的内容,但请记住,应用重新启动后一切都会消失,因为我们没有使用 NSUserDefaults 或 Core Data 将任何内容存储到设备的驱动器中。如果您需要持久性,则需要结合使用这两种方法。

编辑: 至于用数组中的内容填充表格视图,您应该咨询Apple's Docs,因为这里的解释会很长,而且信息很容易找到。或者,您可以查看this article 以了解填充表格视图,或查看this question。您至少需要为您的表格视图实现numberOfSectionsInTableViewnumberOfRowsInSectioncellForRowAtIndexPath

编辑 2: 阅读您的代码后,我想说有很多事情最终可能应该更改,但为了让它现在可以工作,现在需要进行以下更改:

改变这个(来自Save())…

if let Text = txtField.text {
    if txtField.text == "" {
        myArray.append(Text)
        let row = myArray.count-1
        let indexPath = NSIndexPath(forRow: row, inSection: 0)
        embTableVC.myTableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    }
}

……到这个

if let text = txtField?.text {
    if text != "" { // Notice the two changes on this line
        myArray.append(text)
        let row = myArray.count - 1
        let indexPath = NSIndexPath(forRow: row, inSection: 0)
        embTableVC.myTableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    }
}

改变这个(cellForRowAtIndexPath)…

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = myTableView.dequeueReusableCellWithIdentifier("customcell", forIndexPath: indexPath) as UITableViewCell

    cell.textLabel?.text = myArray[indexPath.item]

    return cell
}

……到这个

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = myTableView.dequeueReusableCellWithIdentifier("customcell", forIndexPath: indexPath) as UITableViewCell

    cell.textLabel?.text = myArray[indexPath.row] // Notice `row`, not item`

    return cell
}

如果你仍然因为 nil 可选被解包而导致崩溃,这很有可能,我需要知道 Xcode 在哪一行崩溃,我需要知道错误说明了什么。

【讨论】:

  • 我有一些问题:在var embededTableVC的声明中:TableViewController!我必须写 UITableViewController!而不是 TableViewController (我不知道为什么)。然后,在 override func prepareForSegue 中,override 一词表示“方法不会覆盖其超类中的任何方法”。在 IBAction 函数中,在 embededTableVC.valueArray.append(text) 行中保存单词 valueArray 表示“UITableViewController 类型的值没有成员 valueArray”。非常感谢您的帮助:)
  • 我提供的示例代码需要根据您的设置进行修改。 “TableViewController”代表你命名的 UITableViewController 的自定义类。 “MainViewController”代表您为持有容器和按钮的视图控制器调用自定义类的任何内容。 “override func prepareForSegue”应该放在持有容器的视图控制器的括号内,而不是单独放置。 “valueArray”代表您在代表您的表视图控制器的自定义类上调用的数组。确保在情节提要中指定 IBAction 和自定义类。
  • 我尝试了你给我的建议,但我仍然有一些问题。覆盖函数 prepareForSegue 不起作用,并显示“方法不会覆盖其超类中的任何方法”。如果我删除“覆盖”,问题就会消失。使用 embededTableVC.valueArray.append(text) 它说我“UITableViewController 类型的值没有成员 valueArray。你说我如何解决它们的其他问题现在已经解决了,谢谢:)
  • 你有表视图控制器的自定义类吗?您应该,在这里您将创建一个字符串数组,该数组将在主 VC 中被您称为它的任何名称(在示例中为“valueArray”)引用。如果“prepareForSegue”确实在作为 UIViewController 的子类的主 VC 自定义类中(这是它需要的位置),它应该需要 override 关键字。如有必要,我将创建一个非常简单的示例 Xcode 项目来向您展示设置。
  • 是的,我有一个用于表格视图控制器的自定义类。这里我声明了 var myArray = [String]()。我解决了覆盖函数问题。我尝试编译,但是当我在 textField 中写入字符串时,表格视图没有显示任何内容
【解决方案3】:
import UIKit

class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {      

**var message = ["a","b"]
var toPass: String!**

@IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        // Do any additional setup after loading the view.

        **message.append(toPass)**           
    }    

@IBAction func SendButon(_ sender: UIButton) {
    performSegue(withIdentifier: "segue2", sender: nil)
}      

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

   // tableView.reloadData()
    return message.count
}    

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {    

        tableView.register(UINib(nibName: "TableViewCell", bundle: nil),
                       forCellReuseIdentifier: "CellFor")

        let cell = tableView.dequeueReusableCell(withIdentifier: "CellFor", for: indexPath) as! TableViewCell

        cell.labelView.text = message[indexPath.row]

        return cell       
    }           
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    相关资源
    最近更新 更多