Swift使用新数据更新UITableView [英] Swift updating UITableView with new data

查看:178
本文介绍了Swift使用新数据更新UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用另一个JSON调用的数据重新填充我的 UITableView

I'm trying to repopulate my UITableView with data from another JSON call.

似乎不工作,虽然有很多相同的问题的答案,我可以发现我已经尝试。

However my current setup doesn't seem to work, and while there are many identical questions on SO the answers I could find I've already tried.

我保存我的API数据 CoreData 实体对象。我在我的UITableView填充我的 CoreData 实体。

I'm saving my API data in CoreData entity objects. And I'm filling my UITableView with my CoreData entities.

在我目前的设置我有3个不同的API调用其具有不同的数据量,并且当然具有不同的值。我需要能够在这三个数据集之间切换,这就是我现在想完成的。 (到目前为止没有进展)。

In my current setup I have 3 different API Calls that has a different amount of data, and of course different values. I need to be able to switch between these 3 datasets, and that's what I'm trying to accomplish now. (so far without progress).

我有一个名为loadSuggestions的函数,这是我假设我的错。

I have a function called "loadSuggestions", which is where I assume my fault lies.


  • 首先我检查互联网连接。

  • First I check for an internet connection.

我设置managedObjectContext

I set the managedObjectContext

我检查我需要调用的API(这是在调用函数之前确定的,并且检查它是否按预期工作)

I check what API I need to call (This is determined before the function is called, and I checked that it works as intended)

我从实体尝试调用的所有当前数据。 (我也试图删除数据从最后的数据 UITableView 加载,这没有改变任何东西)。我也检查,这工作。删除数据后,我检查了它打印出一个空数组,我也尝试记录它删除的对象以确保。

I delete all the current data from the entity that it's trying to call. (I also tried to delete the data from the last data the UITableView had loaded. That didn't change anything). I also checked that this works. After deleting the data, I checked that it prints out an empty array, I also tried logging the objects it deletes to make sure.

数据,将其保存到临时变量中。然后将其保存到我的核心数据。

I then fetch the new data, save it into temporary variables. Then save it to my core data.

然后我进行第二次API调用(取决于第一个变量),获取数据并保存同样的方式。

Then I make my second API call (dependant on a variable from the first one), fetch that data and save it the same way.

我将对象添加到数组 UITableView (我检查它也打印输出正确)

I append the object to the array the UITableView fills it's cells from. (I checked that it prints out correctly as well)

最后我重新加载tableView。 (不改变事物)

And lastly I reload the tableView. (doesn't change a thing)

以下是函数:

func loadSuggestions() {
    println("----- Loading Data -----")
    // Check for an internet connection.
    if Reachability.isConnectedToNetwork() == false {
        println("ERROR: -> No Internet Connection <-")
    } else {
        // Set the managedContext again.
        managedContext = appDelegate.managedObjectContext!

        // Check what API to get the data from
        if Formula == 0 {
            formulaEntity = "TrialFormulaStock"
            println("Setting Entity: \(formulaEntity)")
            formulaAPI = NSURL(string: "http://api.com/json/entry_weekly.json")
        } else if Formula == 1 {
            formulaEntity = "ProFormulaStock"
            println("Setting Entity: \(formulaEntity)")
            formulaAPI = NSURL(string: "http://api.com/json/entry_weekly.json")
        } else if Formula == 2 {
            formulaEntity = "PremiumFormulaStock"
            formulaAPI = NSURL(string: "http://api.com/json/proff_weekly.json")
            println("Setting Entity: \(formulaEntity)")
        } else if Formula == 3 {
            formulaEntity = "PlatinumFormulaStock"
            println("Setting Entity: \(formulaEntity)")
            formulaAPI = NSURL(string: "http://api.com/json/fund_weekly.json")
        }

        // Delete all the current objects in the dataset
        let fetchRequest = NSFetchRequest(entityName: formulaEntity)
        let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
        for mo in a {
            managedContext.deleteObject(mo)
        }

        // Removing them from the array
        stocks.removeAll(keepCapacity: false)
        // Saving the now empty context.
        managedContext.save(nil)

        // Set up a fetch request for the API data
        let entity =  NSEntityDescription.entityForName(formulaEntity, inManagedObjectContext:managedContext)
        var request = NSURLRequest(URL: formulaAPI!)
        var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
        var formula = JSON(data: data!)

        // Loop through the api data.
        for (index: String, actionable: JSON) in formula["actionable"] {

            // Save the data into temporary variables
            stockName = actionable["name"].stringValue
            ticker = actionable["ticker"].stringValue
            action = actionable["action"].stringValue
            suggestedPrice = actionable["suggested_price"].floatValue
            weight = actionable["percentage_weight"].floatValue

            // Set up CoreData for inserting a new object.
            let stock = NSManagedObject(entity: entity!,insertIntoManagedObjectContext:managedContext)

            // Save the temporary variables into coreData
            stock.setValue(stockName, forKey: "name")
            stock.setValue(ticker, forKey: "ticker")
            stock.setValue(action, forKey: "action")
            stock.setValue(suggestedPrice, forKey: "suggestedPrice")
            stock.setValue(weight, forKey: "weight")

            // Get ready for second API call.
            var quoteAPI = NSURL(string: "http://dev.markitondemand.com/Api/v2/Quote/json?symbol=\(ticker)")

            // Second API fetch.
            var quoteRequest = NSURLRequest(URL: quoteAPI!)
            var quoteData = NSURLConnection.sendSynchronousRequest(quoteRequest, returningResponse: nil, error: nil)
            if quoteData != nil {
                // Save the data from second API call to temporary variables
                var quote = JSON(data: quoteData!)
                betterStockName = quote["Name"].stringValue
                lastPrice = quote["LastPrice"].floatValue

                // The second API call doesn't always find something, so checking if it exists is important.
                if betterStockName != "" {
                    stock.setValue(betterStockName, forKey: "name")
                }

                // This can simply be set, because it will be 0 if not found.
                stock.setValue(lastPrice, forKey: "lastPrice")

            } else {
                println("ERROR ----------------- NO DATA for \(ticker) --------------")
            }

            // Error handling
            var error: NSError?
            if !managedContext.save(&error) {
                println("Could not save \(error), \(error?.userInfo)")
            }
            // Append the object to the array. Which fills the UITableView
            stocks.append(stock)

        }

        // Reload the tableview with the new data.
        self.tableView.reloadData()
    }
}

目前,当我推到这个viewController,这个函数被调用在 viewDidAppear 像这样:

Currently, when I push to this viewController, this function is called in viewDidAppear like so:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(true)

    tableView.allowsSelection = true
    if isFirstTime {
        loadSuggestions()
        isFirstTime = false
    }
}

tableView正确,一切似乎按计划工作。

It populates the tableView correctly and everything seems to work as planned.

但是,如果我打开我的滑出菜单并调用一个函数来加载不同的数据,没有什么发生,这里是一个示例函数:

However if I open my slide-out menu and call a function to load different data, nothing happens, here's an example function:

func platinumFormulaTapGesture() {
    // Menu related actions
    selectView(platinumFormulaView)
    selectedMenuItem = 2
    // Setting the data to load
    Formula = 3
    // Sets the viewController. (this will mostly be the same ViewController)
    menuTabBarController.selectedIndex = 0
    // Set the new title
    navigationController?.navigationBar.topItem!.title = "PLATINUM FORMULA"
    // And here I call the loadSuggestions function again. (this does run)
    SuggestionsViewController().loadSuggestions()
}

以下是2个相关的tableView函数:

Here's the 2 relevant tableView functions:

行数:

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

和cellForRowAtIndexPath

And cellForRowAtIndexPath, (this is where I set up my cells with the CoreData)

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("com.mySuggestionsCell", forIndexPath: indexPath) as! mySuggestionsCell

    let formulaStock = stocks[indexPath.row]
    cell.stockNameLabel.text = formulaStock.valueForKey("name") as! String!
    cell.tickerLabel.text = formulaStock.valueForKey("ticker") as! String!
    action = formulaStock.valueForKey("action") as! String!
    suggestedPrice = formulaStock.valueForKey("suggestedPrice") as! Float

    let suggestedPriceString = "Suggested Price\n$\(suggestedPrice.roundTo(2))" as NSString
    var suggestedAttributedString = NSMutableAttributedString(string: suggestedPriceString as String)

    suggestedAttributedString.addAttributes(GrayLatoRegularAttribute, range: suggestedPriceString.rangeOfString("Suggested Price\n"))
    suggestedAttributedString.addAttributes(BlueHalisRBoldAttribute, range: suggestedPriceString.rangeOfString("$\(suggestedPrice.roundTo(2))"))
    cell.suggestedPriceLabel.attributedText = suggestedAttributedString

    if action == "SELL" {
        cell.suggestionContainer.backgroundColor = UIColor.formulaGreenColor()
    }

    if let lastPrice = formulaStock.valueForKey("lastPrice") as? Float {
        var lastPriceString = "Last Price\n$\(lastPrice.roundTo(2))" as NSString
        var lastAttributedString = NSMutableAttributedString(string: lastPriceString as String)

        lastAttributedString.addAttributes(GrayLatoRegularAttribute, range: lastPriceString.rangeOfString("Last Price\n"))

        percentDifference = ((lastPrice/suggestedPrice)*100.00)-100

        if percentDifference > 0 && action == "BUY" {
            lastAttributedString.addAttributes(RedHalisRBoldAttribute, range: lastPriceString.rangeOfString("$\(lastPrice.roundTo(2))"))
        } else if percentDifference <= 0 && percentDifference > -100 && action == "BUY" {
            lastAttributedString.addAttributes(GreenHalisRBoldAttribute, range: lastPriceString.rangeOfString("$\(lastPrice.roundTo(2))"))
        } else if percentDifference <= 0 && percentDifference > -100 && action == "SELL" {
            lastAttributedString.addAttributes(RedHalisRBoldAttribute, range: lastPriceString.rangeOfString("$\(lastPrice.roundTo(2))"))
        } else if percentDifference == -100 {
            lastPriceString = "Last Price\nN/A" as NSString
            lastAttributedString = NSMutableAttributedString(string: lastPriceString as String)

            lastAttributedString.addAttributes(GrayLatoRegularAttribute, range: lastPriceString.rangeOfString("Last Price\n"))
            lastAttributedString.addAttributes(BlackHalisRBoldAttribute, range: lastPriceString.rangeOfString("N/A"))
        }

        cell.lastPriceLabel.attributedText = lastAttributedString
    } else {
        println("lastPrice nil")
    }

    weight = formulaStock.valueForKey("weight") as! Float
    cell.circleChart.percentFill = weight
    let circleChartString = "\(weight.roundTo(2))%\nWEIGHT" as NSString
    var circleChartAttributedString = NSMutableAttributedString(string: circleChartString as String)
    circleChartAttributedString.addAttributes(BlueMediumHalisRBoldAttribute, range: circleChartString.rangeOfString("\(weight.roundTo(2))%\n"))
    circleChartAttributedString.addAttributes(BlackSmallHalisRBoldAttribute, range: circleChartString.rangeOfString("WEIGHT"))
    cell.circleChartLabel.attributedText = circleChartAttributedString

    cell.selectionStyle = UITableViewCellSelectionStyle.None
    return cell
}

我定义了我的appDelegate作为我类中的第一件事:

I define my appDelegate as the very first thing in my class:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var managedContext = NSManagedObjectContext()



我认为这是所有可能的代码错误的原因。我再次认为最可能的原因是在 loadSuggestions 函数。

强制更新tableView我也试过在 self.view 上调用 setNeedsDisplay setNeedsLayout code> tableView ,这两个都没有做任何事情。

To force update the tableView I also tried calling setNeedsDisplay and setNeedsLayout both on self.view and tableView, neither of which seemed to do anything at all.

任何建议在找出为什么这个tableView拒绝更新将是一个巨大的帮助!

Any advice in figuring out why this tableView refuses to update would be an enormous help!

我为代码的墙壁道歉,但我没有找到问题的确切起源。

And I apologize for the walls of code, but I havn't been able to find the exact origin of the issue.

推荐答案

platinumFormulaTapGesture函数中的此行不正确,

This line in the platinumFormulaTapGesture function is incorrect,

SuggestionsViewController().loadSuggestions()

这会创建一个SuggestionsViewController的新实例,不是你在屏幕上的那个。你需要得到一个指针,你有一个。这样做取决于您的控制器层次结构,您没有充分解释。

This creates a new instance of SuggestionsViewController, which is not the one you have on screen. You need to get a pointer to the one you have. How you do that depends on your controller hierarchy, which you haven't explained fully enough.

这篇关于Swift使用新数据更新UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆