标签打印到表格视图中的错误单元格

Posted

技术标签:

【中文标题】标签打印到表格视图中的错误单元格【英文标题】:Labels printing to wrong cells in table view 【发布时间】:2017-01-24 18:00:38 【问题描述】:

我正在使用 Alamofire 和 SwiftyJSON 从 YQL 获取股票,将它们保存到我的核心数据“公司”对象,然后使用标签中的数据,如下所示:

尝试的代码:

func fetchStocks() 

let entity = NSEntityDescription.entity(forEntityName: "Company", in: managedContext)!
var prices = [String]()

if let data = try? Data(contentsOf: URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22AAPL%22%2C%22GOOG%22%2C%22TWTR%22%2C%22TSLA%22%2C%20%22FB%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!) 
    let json = JSON(data: data)
    print(json)
    if let appleStockPrice = json["query"]["results"]["quote"][0]["Ask"].string 
        prices.append(appleStockPrice)
    
    if let googleStockPrice = json["query"]["results"]["quote"][1]["Ask"].string 
        prices.append(googleStockPrice)
    
    if let twitterStockPrice = json["query"]["results"]["quote"][2]["Ask"].string 
        prices.append(twitterStockPrice)
    
    if let teslaStockPrice = json["query"]["results"]["quote"][3]["Ask"].string 
        prices.append(teslaStockPrice)
    
    if let facebookStockPrice = json["query"]["results"]["quote"][4]["Ask"].string 
        prices.append(facebookStockPrice)
    
    for stocks in prices 
        let company = NSManagedObject(entity: entity,insertInto: managedContext)
        company.setValue(stocks, forKey: "stockPrice")
        companies.append(company)
    
    do 
        try managedContext.save()
        vc.tableView.reloadData()
     catch let error as NSError 
        print("Could not save. \(error), \(error.userInfo)")
    


当我尝试将价格设置为详细的文本标签时

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

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! Cell
    let company = companies[indexPath.row]


    cell.textLabel?.text = company.value(forKey: "name") as? String

    cell.detailTextLabel?.text = "Current stock price: \(company.value(forKey: "stockPrice") as? String)"

    return cell

我明白了:

因此,股票价格被获取,但没有被放入公司的单元格中 - 相反,这些值为零,股票价格进入单独的单元格。

为什么会发生这种情况,我该如何解决?

编辑:发布整个 cellForRow 方法,这里是 YQL JSON:


  "query" : 
"created" : "2017-01-24T18:12:06Z",
"results" : 
  "quote" : [
    
      "symbol" : "AAPL",
      "YearLow" : "89.470",
      "YearHigh" : "120.810",
      "Ask" : "119.990"
    ,
    
      "symbol" : "GOOG",
      "YearLow" : "663.06",
      "YearHigh" : "824.87",
      "Ask" : "821.70"
    ,
    
      "symbol" : "TWTR",
      "YearLow" : "13.73",
      "YearHigh" : "25.25",
      "Ask" : null
    ,
    
      "symbol" : "TSLA",
      "YearLow" : "141.0500",
      "YearHigh" : "269.3400",
      "Ask" : "253.4100"
    ,
    
      "symbol" : "FB",
      "YearLow" : "94.23",
      "YearHigh" : "133.50",
      "Ask" : "128.67"
    
  ]
,
"count" : 5,
"lang" : "en-us"
  

编辑 2:设置名称、徽标和 stockPrices

func setDefaultCompanies() 

    // Default 5 companies at launch - user can delete/add/edit

    let userDefaults = UserDefaults.standard
    let defaultValues = ["firstRun" : true]
    userDefaults.register(defaults: defaultValues)

    if userDefaults.bool(forKey: "firstRun") 

        let entity = NSEntityDescription.entity(forEntityName: "Company", in: managedContext)!
        let defaultCompanies = ["Apple", "Google", "Facebook", "Tesla", "Twitter"]

        for companyName in defaultCompanies 
            let company = NSManagedObject(entity: entity,insertInto: managedContext)
            company.setValue(companyName, forKey: "name")
            company.setValue(companyName, forKey: "logo")
            companies.append(company)
        
        fetchStocks()
        do 
            try managedContext.save()
            userDefaults.set(false, forKey: "firstRun")
            vc.tableView.reloadData()
         catch let error as NSError 
            print("Could not save. \(error), \(error.userInfo)")
        
    

【问题讨论】:

您需要向我们展示cellForRowAtindexPath的完整代码。 粘贴整个 cellForRow 方法。示例 json 也会有所帮助 我编辑添加了 cellForRow 和 JSON(Alistra,我认为您要求的是从 YQL 请求返​​回的 JSON,如果您的意思不同,请告诉我) 您仅使用引号创建 NSManagedObject 实例。名称分配在哪里? @vadian 几天前你实际上帮我取了名字,我将在这里编辑我的问题以显示代码(那里也调用了 fetchStocks 函数) 【参考方案1】:

您的代码无法运行。您正在执行以下操作:

创建默认公司(添加 5 个NSManagedObject 实例) 获取库存值。 创建新公司(添加另外 5 个NSManagedObject 实例)。

现在您有 10 个条目而不是 5 个。


我的建议:

创建文件Localizable.strings,将公司符号映射到真实姓名

"AAPL" = "Apple";
"TSLA" = "Tesla";
"TWTR" = "Twitter";
"GOOG" = "Google";
"FB" = "FaceBook";

然后首先获取股票价值。

在循环中通过NSLocalizedString(comment:)从密钥symbol获取真实姓名,创建NSManagedObject实例并设置属性。

这使用异步方式加载数据并替换setDefaultCompanies() fetchStocks()(未经测试)

func setDefaultCompanies() 

    // Default 5 companies at launch - user can delete/add/edit

    let userDefaults = UserDefaults.standard
    let defaultValues = ["firstRun" : true]
    userDefaults.register(defaults: defaultValues)

    if userDefaults.bool(forKey: "firstRun") 
        let entity = NSEntityDescription.entity(forEntityName: "Company", in: managedContext)!

        let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22AAPL%22%2C%22GOOG%22%2C%22TWTR%22%2C%22TSLA%22%2C%20%22FB%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
        let task = URLSession.shared.dataTask(with: url)  (data, response, error) in
            if error != nil 
                print(error!) // or display an alert view
             else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 
                let json = JSON(data: data!)
                if let quotes = json["query"]["results"]["quote"].array 
                    for quote in quotes 
                        let symbol = quote["symbol"].stringValue
                        let name = NSLocalizedString(symbol, comment:"")
                        let ask = quote["Ask"].stringValue
                        let company = NSManagedObject(entity: entity,insertInto: self.managedContext)
                        company.setValue(name, forKey: "name")
                        company.setValue(name, forKey: "logo")
                        company.setValue(ask, forKey: "stockPrice")
                        self.companies.append(company)
                    
                    DispatchQueue.main.async 
                       do 
                           try self.managedContext.save()
                           self.vc.tableView.reloadData()
                           userDefaults.set(false, forKey: "firstRun")
                        catch let error as NSError 
                           print("Could not save. \(error), \(error.userInfo)")
                       
                   
                
             else 
                print("The data couldn't be loaded") // or display an alert view
            
        
        task.resume()
    

【讨论】:

这是正确的做法。您不想创建“默认公司”,您应该在获得股票价值后尝试创建公司。 @vadian 谢谢!我必须阅读本地化字符串,然后尝试这个解决方案。感谢您最近提供的所有帮助。 @vadian 我刚刚做了一个关于本地化字符串的教程——很酷的东西!您的解决方案也有效,但有趣的是,它仅在我在 for 循环末尾放置一个 print 语句时才有效。如果没有打印语句,我只会得到一个空表视图。添加打印语句使其工作,但没有任何内容打印到控制台。也许是一个奇怪的错误,但无论您的解决方案是否有效,非常感谢您!【参考方案2】:

您的单元格未正确出列。仅当单元格在 tableview 中滚动但未出队以保留其内容时,才会出现此问题。

【讨论】:

单元格以let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! Cell出列,有不同的方法吗? 重用单元格不是真正的问题。

以上是关于标签打印到表格视图中的错误单元格的主要内容,如果未能解决你的问题,请参考以下文章

在表格视图中点击按钮 - 错误的单元格

如何组织表格视图单元格

将表格视图快速添加到表格视图单元格中的问题

表格视图单元格中的自增长标签

设置表格视图单元格的高度以匹配底部到标签栏顶部

自动布局 - 在表格单元格中对齐视图