NSUserDefault 同步后退按钮 swift

Posted

技术标签:

【中文标题】NSUserDefault 同步后退按钮 swift【英文标题】:NSUserDefault synchronize on back button swift 【发布时间】:2016-05-19 08:35:22 【问题描述】:

我的 UITableView 有问题。我有 3 个带有导航控制器的视图。第二个有一个表,第三个是带有一些值的搜索。我想单击按钮搜索(第三个视图)并打开第二个视图并更新表格。但不更新。要工作,我必须返回第一个视图并再次打开第二个视图。

第二次查看代码:

class Empresa: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate

let textCellIdentifier = "cell"
var menu:[[String]] = [[]]
var buscaEmp:BuscadorEmpresa = BuscadorEmpresa()


@IBOutlet weak var tablaVista: UITableView!


override func viewDidLoad() 
    super.viewDidLoad()
    recuperaEmpresas()
    tablaVista.delegate = self
    tablaVista.dataSource = self



func recuperaEmpresas()

    menu = buscaEmp.getEmpresas()



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


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


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

    return menu.count





func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! CustomTableViewCell

    let row = indexPath.row
    cell.nombreEmp.text = menu[row][0]
    return cell



override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)
    recuperaEmpresas()
    self.tablaVista.reloadData()


如您所见,我在 viewWillAppear 上重新加载了我的 tableView (tablaVista) 但不更新。

RecuperaEmpresa()调用这个方法:

 func getEmpresas() -> [[String]]
    NSUserDefaults.standardUserDefaults().synchronize()

    var array = [[""]]
     if((NSUserDefaults.standardUserDefaults().arrayForKey("ARRAYEMPRESA")) != nil)
array = NSUserDefaults.standardUserDefaults().arrayForKey("ARRAYEMPRESA")! as! [[String]]
return array

return array 

我在调试,就像getEmpresa第一次不要更新

编辑:

GetEmpresa 第一次不返回最后一个值,但如果我打印返回正确的值。问题一定是NSUSERDEFAULT

用图像编辑

为亚历山德罗·奥纳诺编辑

最后我的 tableView 重新加载,但我立即看到我的最后一个值并用新闻改变它。我用那个:

第二个视图:

let textCellIdentifier = "cell"
var menu:[[String]] = [[]]
//var buscaEmp:BuscadorEmpresa = BuscadorEmpresa()


@IBOutlet weak var tablaVista: UITableView!


override func viewDidLoad() 

    super.viewDidLoad()
    recuperaEmpresas()
    tablaVista.delegate = self
    tablaVista.dataSource = self



func recuperaEmpresas()
    self.menu = NSUserDefaults.standardUserDefaults().arrayForKey("ARRAYEMPRESA")! as! [[String]]
    //self.menu = buscaEmp.getEmpresas()



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


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


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

    return menu.count





func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! CustomTableViewCell

    let row = indexPath.row
    cell.nombreEmp.text = menu[row][0]
    return cell



override func viewDidAppear(animated: Bool) 
    super.viewDidAppear(animated)
    recuperaEmpresas()
    viewDidLoad()
    self.tablaVista.reloadData()


第三视图按钮调用此方法:

request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) 
        data, response, error in
        if error != nil
        
            print("error=\(error)")
            return
        

        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        var err: NSError?
        do
            let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)

            let jsonEmpresas = myJSON["TablaEmp"]!!["item"]
            let empresas: [[String: AnyObject]]

            if let multipleEmpresas = jsonEmpresas as? [[String: AnyObject]] 
                empresas = multipleEmpresas
             else if let singleEmpresa = jsonEmpresas as? [String: AnyObject] 
                empresas = [singleEmpresa]
             else 
                empresas = []
            

            for empresa in empresas
                let zcif = empresa["Zcif"] as? String
                let zcccp = empresa["Zcccp"] as? String
                let zfax = empresa["Zfax"] as? String
                let zdocu = empresa["Zdocu"] as? String
                self.arrayEmpresas.append([zcif!, zcccp!, zfax!, zdocu!])


            
            NSUserDefaults.standardUserDefaults().setObject(self.arrayEmpresas, forKey:"ARRAYEMPRESA")
            NSUserDefaults.standardUserDefaults().synchronize()


        catch  print(error)
    
    task.resume()

还有

 func back()
    navigationController?.popViewControllerAnimated(true)

获取方法:

func getEmpresas() -> [[String]]
    NSUserDefaults.standardUserDefaults().synchronize()

    var array = [[""]]

    if((NSUserDefaults.standardUserDefaults().arrayForKey("ARRAYEMPRESA")) != nil)
    array = NSUserDefaults.standardUserDefaults().arrayForKey("ARRAYEMPRESA")! as! [[String]]
    return array
    
    return array

【问题讨论】:

您是说要显示在TableView 中的数据是从第二个ViewController 本身修改的,并且更改不会在TableView 中更新?用户默认值在哪里修改? 在 thirdView 的 viewWillDisappear: 方法中更新 serachValue 并在 secondView 的 viewDidAppear: 方法中重新加载您的表格 @TheTiger 我试过但还是不行 【参考方案1】:

当您多次遇到此类问题时,会涉及采样数据和 UI 更新之间的同步。在你的代码中,我不知道你从哪里得到这些数据,需要多长时间才能到达以及你如何在 NSUserDefaults 上设置这个数组。因此,如果您无法立即看到您的 UI 更新,则可能是您过早启动 reloadData(主线程),因为后台线程仍有操作(http 服务器查询、数据获取......)

你也可以写一个更优雅的:

func getEmpresas() -> [String] 
    NSUserDefaults.standardUserDefaults().synchronize()
    if let array = NSUserDefaults.standardUserDefaults().arrayForKey("ARRAYEMPRESA")! as! [[String]] 
                    return array
    
    return [String]()

更新: 我看过你的更新代码。我想把你的注意力集中在这个方法上:

func recuperaEmpresas()
    // Are my data ready to read??? who can say to me this in main thread?? 
    menu = buscaEmp.getEmpresas()

所以你不能打电话给self.tablaVista.reloadData(),直到你很确定你的数据可以存在。为此,您可以使用completion handler(如果您想知道如何构建它,请点击我)

func recuperaEmpresas(url: NSURL,completionHandler: CompletionHandler)
        callMyNetwork()  //do call and after finish do...
           menu = buscaEmp.getEmpresas()
           self.tablaVista.reloadData()
        

【讨论】:

这不是错误,因为结果类似于 [["123","456"], ["789","000"]] 是数组数组 你能添加一些关于 http 数据获取的代码,以及在你拥有这些数据后你在哪里设置 NSUserDefaults 吗? 已更新(为 Alessandro Ornano 编辑)。谢谢 我正在阅读有关完成处理程序的内容并且有一些问题(这对我来说真的很难)。1- callMyNetwork() 是什么? 2-我必须声明 typealias CompletionHandler = (success:Bool) -> Void 对吗? 3- 当我在 viewDidLoad 和 viewDidAppear 上调用方法时,我必须发送一些参数,但不明白为什么。 不必在任何地方调用你的网络调用方法(调用我的网络),例如你可以只在 viewDidAppear 中使用它,完成后你必须刷新 ui【参考方案2】:

尝试将 tableVista.reloadData() 放入您的 prepareForSegueunwindToHome 函数中(无论您使用哪个返回到第二个视图)。如果这不可行,您始终可以设置一个 bool var 来确定视图是从第一个视图还是第二个视图加载,然后相应地重新加载数据。

希望这会有所帮助。 :)

【讨论】:

以上是关于NSUserDefault 同步后退按钮 swift的主要内容,如果未能解决你的问题,请参考以下文章

从 NSUserDefault 保存和检索数据时,保存按钮无法正常工作

滚动存储在 NSUserDefault 中的 UITextField 上的 UITableView 更改数据

如何在 appdelegate 中使用 applicationDidEnterBackground 保存 NSUserDefault

使用NSUserDefault存储大量数据有啥缺点

如何使用智能手机后退按钮作为 webview 后退按钮?

用iframe后 点后退按钮时总是在潜套框里后退,如何让整个父页面整体后退呢?