标签打印到表格视图中的错误单元格
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
出列,有不同的方法吗?
重用单元格不是真正的问题。以上是关于标签打印到表格视图中的错误单元格的主要内容,如果未能解决你的问题,请参考以下文章